首页
统计
友链
关于
Search
1
静静地生活着
411 阅读
2
JVM_1.引言
401 阅读
3
Chapter 03
328 阅读
4
机器学习 01
318 阅读
5
欢迎使用 Typecho
280 阅读
Java
School
ML
Other
Share
Explore
运维
登录
Search
bbchen
累计撰写
53
篇文章
累计收到
5
条评论
首页
栏目
Java
School
ML
Other
Share
Explore
运维
页面
统计
友链
关于
搜索到
31
篇与
的结果
2023-02-26
Chapter15_泛型
泛型泛型的理解和好处编译时,检查添加元素的类型,提高了安全性减少了类型转换的次数,提高效率不再提示编译警告package com.bbedu.generic.improve; import java.util.ArrayList; public class Generic02 { public static void main(String[] args) { // 这样写时,ArrayList<Dog> 表示存放到集合中的元素是 Dog 类型 // 如果添加类型不满足要求,编译器会报错 // 相当于加入约束 // 在遍历时,可以直接取出 Dog 类型,而不是 Object ArrayList<Dog> arrayList = new ArrayList<Dog>(); arrayList.add(new Dog("旺财", 10)); arrayList.add(new Dog("发财", 5)); arrayList.add(new Dog("大黄", 6)); // 放入猫 //arrayList.add(new Cat("招财猫", 3)); for (Dog dog:arrayList) { System.out.println(dog.getName()+ "-" + dog.getAge()); } } } class Dog { private String name; private int age; public Dog(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } class Cat{ private String name; private int age; public Cat(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }泛型介绍泛型又称参数化类型,是 jdk5.0 出现的新特性,解决数据类型的安全性问题在类声明或实例化时只要指定好需要的具体的类型即可Java 泛型可以保证如果程序在编译时没有翻出警告,运行时就不会产生 ClassCastException 异常,同时,代码更加简洁、健壮泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型泛型的语法声明interface 接口<T>{} 和 class 类<K, V>{}说明:其中,T,K,V不代表值,而是表示类型任意字母都可以,常用 T 表示,short of Type实例化要在类名后面指定类型参数的值(类型),如:List<String> strList = new ArrayList<String>();Iterator<Customer> iterator = customers.iterator();细节interface List<T>{}, public class HashSet<E>{}...说明:T,E只能是引用类型在给泛型指定具体类型后,可以传入该类型或该类型的子类型泛型的使用形式List<Integer> list1 = new ArrayList<Integer>();可简化为:// 编译器会进行类型推断,推荐这种写法:List<Integer> list2 = new ArrayList<>();如果是这样写:ArrayList arrayList = new ArrayList();等价于:ArrayList<Object> arrayList = new ArrayList<>();练习 p560package com.bbedu.generic.exercise; import java.util.ArrayList; import java.util.Comparator; import java.util.Objects; public class Exercise01 { public static void main(String[] args) { Employee jack = new Employee("Jack", 20000, new MyDate(1999, 1, 1)); Employee jack2 = new Employee("Jack", 25000, new MyDate(1999, 1, 2)); Employee mike = new Employee("Mike", 15000, new MyDate(2000, 2, 6)); Employee sam = new Employee("Sam", 30000, new MyDate(1989, 10, 1)); Employee tim = new Employee("Tim", 10000, new MyDate(2002, 4, 1)); Employee tim2 = new Employee("Tim", 10000, new MyDate(2001, 4, 1)); ArrayList<Employee> employees = new ArrayList<>(); employees.add(sam); employees.add(jack2); employees.add(jack); employees.add(mike); employees.add(tim); employees.add(tim2); System.out.println("===排序前==="); System.out.println(employees); employees.sort(new Comparator<Employee>() { @Override public int compare(Employee o1, Employee o2) { if(!(o1 instanceof Employee && o2 instanceof Employee)){ System.out.println("类型不正确..."); return 0; } if(o1.getName().compareTo(o2.getName()) != 0){ return o1.getName().compareTo(o2.getName()); } // 封装提升可维护性和复用性 return o1.getBirthday().compareTo(o2.getBirthday()); } }); System.out.println("===排序后==="); System.out.println(employees); } } class Employee { private String name; private double sal; private MyDate birthday; public Employee(String name, double sal, MyDate birthday) { this.name = name; this.sal = sal; this.birthday = birthday; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public MyDate getBirthday() { return birthday; } public void setBirthday(MyDate birthday) { this.birthday = birthday; } @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", sal=" + sal + ", birthday=" + birthday + '}' + "\n"; } } class MyDate implements Comparable<MyDate>{ private int year; private int month; private int day; public MyDate(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MyDate myDate = (MyDate) o; return year == myDate.year && month == myDate.month && day == myDate.day; } @Override public int hashCode() { return Objects.hash(year, month, day); } @Override public String toString() { return "MyDate{" + "year=" + year + ", month=" + month + ", day=" + day + '}'; } @Override public int compareTo(MyDate o) { int yearMinus = year - o.getYear(); if(yearMinus != 0){ return yearMinus; } int monthMinus = month - o.month; if (monthMinus != 0) { return monthMinus; } return day - o.day; } }自定义泛型泛型类普通成员可以使用泛型(属性、方法)使用泛型的数组,不能初始化静态方法中不能使用类的泛型泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)如果在创建对象时,没有指定类型,默认为Object泛型接口接口中,静态成员不能使用泛型泛型接口的类型,是在继承接口或者实现接口时实现的没有指定类型时,默认为 Object泛型方法基本语法:修饰符 <T, R> 返回方法 方法名(参数列表) {}泛型方法,可以定义在普通类中,也可以定义在泛型类中当泛型方法被调用时,类型也会被确定修饰符 返回方法 方法名(参数列表){}不是泛型方法,是使用了泛型的方法泛型继承和通配符泛型没有继承机制例如:List list = new ArrayList(); // 错误<?>: 支持任意类型的泛型<? extend AA> : 表示上限,可以接收 AA 或 AA 的子类<? super AA>: 表示下限,可以接收 AA 或 AA 的父类本章作业JUnit一个类有很多功能代码需要测试,为了测试,就需要写到 main 方法中如果有多个功能代码测试,就需要来回注销,切换很麻烦如果可以直接运行一个方法,就方便很多,并且可以给出相关信息 -> JUnitpackage com.bbedu.generic.homework; import org.junit.jupiter.api.Test; import java.util.*; public class Homework01 { @Test public void testList() { DAO<User> dao = new DAO<>(); dao.save("001", new User(1, 10, "Jack")); dao.save("002", new User(2, 12, "Tom")); dao.save("003", new User(3, 14, "Mary")); System.out.println(dao.list()); dao.update("003", new User(3, 23, "Milan")); System.out.println(dao.list()); dao.delete("001"); System.out.println(dao.list()); System.out.println(dao.get("003")); } } class DAO<T> { private Map<String, T> map = new HashMap<>(); public T get(String id) { return map.get(id); } public void update(String id, T entity) { map.put(id, entity); } public List<T> list() { List<T> list = new ArrayList<>(); Set<String> strings = map.keySet(); for (String string : strings) { list.add(get(string)); } return list; } public void delete(String id) { map.remove(id); } public void save(String id, T entity) { map.put(id, entity); } } class User { private int id; private int age; private String name; public User(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", age=" + age + ", name='" + name + '\'' + '}'; } }
2023年02月26日
41 阅读
0 评论
0 点赞
2023-02-26
Chapter14_集合
集合集合的框架体系CollectionCollection 接口实现类的特点public interface Collection extends Iterablecollection 实现子类可以存放多个元素,每个元素可以是 Object有些 Collection 的实现类,可以存放重复的元素,有些不可以Collection 的实现类,有些是有序的(List),有些不是有序的(Set)Collection 接口没有直接实现子类,是通过它的子接口 Set 和 List 来实现的常用方法package com.bbedu.collection_; import java.util.ArrayList; import java.util.List; @SuppressWarnings({"all"}) public class CollectionMethod { public static void main(String[] args) { List list = new ArrayList(); // add list.add("Tim"); list.add(10); // 相当于list.add(new Integer(10)) list.add(true); System.out.println("list=" + list); // remove list.remove(0); // 删除第一个元素 list.remove((Integer) 10); System.out.println("list=" + list); // contains System.out.println(list.contains(true)); // size System.out.println(list.size()); // isEmpty System.out.println(list.isEmpty()); // clear list.clear(); System.out.println("list=" + list); // addAll ArrayList list2 = new ArrayList(); list2.add("红楼梦"); list2.add("三国演义"); list.addAll(list2); System.out.println("list=" + list); // containsAll System.out.println(list.containsAll(list2)); // removeAll list.add("Macbeth"); list.removeAll(list2); System.out.println("list=" + list); } }迭代器遍历Iterable 类中,可以返回一个 Iterator 对象,迭代器,可以用来遍历Iterator对象称为迭代器,主要用于遍历Collection集合中的元素。所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了lterator接口的对象,即可以返回一个迭代器。lterator的结构:Iterator仅用于遍历集合,Iterator本身并不存放对象。增强 for 循环增强 for 循环,可以替代 iterator 迭代器,特点:增强 for 就是简化版的 iterator,本质相同。但只能用于遍历集合和数组基本语法:for(元素类型 元素名 : 集合名或数组名){ 访问元素;}练习package com.bbedu.collection_; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class CollectionExercise { public static void main(String[] args) { List<Dog> dogs = new ArrayList<>(); Dog dog1 = new Dog("小黑", 3); Dog dog2 = new Dog("大黄", 5); Dog dog3 = new Dog("旺财", 6); dogs.add(dog1); dogs.add(dog2); dogs.add(dog3); Iterator<Dog> iterator = dogs.iterator(); System.out.println("=====迭代器====="); while (iterator.hasNext()) { Dog next = iterator.next(); System.out.println(next); } System.out.println("=====增强for循环====="); for (Dog dog : dogs) { System.out.println(dog); } } } class Dog { private String name; private int age; public Dog(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } }List 接口基本介绍List 接口是 Collection 接口的子接口List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复List集合中的每个元素都有其对应的顺序索引,即支持索引List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素常用方法package com.bbedu.list_; import java.util.ArrayList; import java.util.List; public class ListMethod { public static void main(String[] args) { // add ArrayList list = new ArrayList(); list.add("计算机组成原理"); list.add("操作系统"); list.add(1, "数据结构"); // 插入指定位置 System.out.println("list=" + list); // addAll ArrayList list2= new ArrayList(); list2.add("Tim"); list2.add("Mike"); list.addAll(1, list2); System.out.println("list=" + list); // indexOf lastIndexOf System.out.println(list.indexOf("Tim")); list.add("Tim"); System.out.println(list.lastIndexOf("Tim")); // remove list.remove(0); System.out.println("list=" + list); // set 相当于替换 list.set(0, "Jim"); System.out.println("list=" + list); // subList 范围:[fromIndex, toIndex) List retList = list.subList(0, 2); System.out.println("returnList=" + retList); } }List 的三种遍历iterator增强 for普通 for练习package com.bbedu.list_; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Vector; public class ListExercise02 { public static void main(String[] args) { List list = new ArrayList(); // List list = new LinkedList(); // List list = new Vector(); list.add(new Book("红楼梦", 100, "曹雪芹")); list.add(new Book("西游记", 10, "吴承恩")); list.add(new Book("水浒传", 19, "施耐庵")); list.add(new Book("三国演义", 20, "罗贯中")); list.add(new Book("西游记", 10, "吴承恩")); for (Object o : list) { System.out.println(o); } sort(list); System.out.println("=====排序后====="); for (Object o : list) { System.out.println(o); } } public static void sort(List list){ for (int i = 0; i < list.size() - 1; i++) { for (int j = 0; j < list.size() - i - 1; j++) { Book book1 = (Book) list.get(j); Book book2 = (Book) list.get(j + 1); if(book1.getPrice() > book2.getPrice()){ list.set(j, book2); list.set(j+1, book1); } } } } } class Book { private String name; private int price; private String author; public Book(String name, int price, String author) { this.name = name; this.price = price; this.author = author; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } @Override public String toString() { return "名称:" + name + "\t 价格:" + price + "\t 作者:" + author; } }ArrayList注意事项permits all elements, including nullArrayList 是由数组来实现数据存储的ArrayList 基本等同于 Vector,除了 ArrayList 是线程不安全,在多线程情况下,不建议使用 ArrayList底层结构和源码分析先结论,再源码ArrayList中维护了一个Object类型的数组elementData. [debug 看源码]transient Object[] elementData; //transient表示瞬间,短暂的,表示该属性不会被序列化当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。package com.bbedu.list_; import java.util.ArrayList; import java.util.Vector; public class ArrayListSource { public static void main(String[] args) { ArrayList list = new ArrayList(8); for (int i = 1; i <= 10; i++) { list.add(i); } for (int i = 11; i <= 15; i++) { list.add(i); } list.add(100); list.add(200); list.add(300); } }初始为10:若先指定 ArrayList 大小,底层类似,不再赘述Vector注意事项Vector 类的定义说明Vector 底层也是一个对象数组,protected Object[] elementData;Vector 是线程同步的,即线程安全,Vector 类的操作方法带有 synchronized在开发中,需要线程同步安全时,考虑使用 VectorVector 和 ArrayList 比较扩容源码分析package com.bbedu.list_; import java.util.Vector; @SuppressWarnings({"all"}) public class Vector_ { public static void main(String[] args) { Vector vector = new Vector(); for (int i = 0; i < 10; i++) { vector.add(i); } vector.add(100); } }LinkedListLinkedList 底层实现了双向链表和双向队列特点可以添加任意元素(元素可以重复),包括 null线程不安全,没有实现同步LinkedList 的底层操作机制LinkedList 底层维护了一个双向链表LinkedList 中维护了两个属性 first 和 last 分别指向 首节点和尾节点每个节点(Node对象)里又维护了 prev、next、item 三个属性,其中通过 prev 指向前一个,通过 next 指向后一个节点,最终实现双向链表LinkedList 的元素的添加和删除,不是通过数组完成的,因此效率相对较高package com.bbedu.list_; import java.util.Iterator; import java.util.LinkedList; @SuppressWarnings({"all"}) public class LinkedListCRUD { public static void main(String[] args) { LinkedList linkedList = new LinkedList(); linkedList.add(1); linkedList.add(2); linkedList.add(3); System.out.println("linkedList=" + linkedList); linkedList.remove(); // 默认删除第一个节点 System.out.println("linkedList=" + linkedList); linkedList.set(0, 999); System.out.println("linkedList=" + linkedList); linkedList.get(1); System.out.println(linkedList.get(1)); Iterator iterator = linkedList.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println("next=" + next); } for (Object o : linkedList) { System.out.println("o=" + o); } } }jdk底层研究方法类似,请自行研究。ArrayList 和 LinkedList 比较如何选择ArrayList和LinkedList:如果我们改查的操作多,选择ArrayList如果我们增删的操作多,选择LinkedList一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList, 另外一个模块是 LinkedList.Set 接口基本介绍无序(添加和取出的顺序不一致),没有索引不允许重复元素,所以最多包含一个nullJDK API 中 Set 接口的实现类有:常用方法和 List 接口一样,Set 接口也是 Collection 的子接口,因此常用方法和 Collection 接口一样遍历方法同 Collection 的遍历方式一样,因为 Set 接口是 Collection 接口的子接口:可以使用迭代器增强 for 循环不能使用 索引的方式来获取package com.bbedu.set_; import java.util.HashSet; import java.util.Iterator; import java.util.Set; @SuppressWarnings({"all"}) public class SetMethod { public static void main(String[] args) { Set set = new HashSet(); set.add("john"); set.add("lucy"); set.add("john"); set.add("job"); set.add(null); System.out.println("set=" + set); System.out.println("====迭代器===="); Iterator iterator = set.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println("next=" + next); } set.remove(null); System.out.println("====增强for===="); for (Object o : set) { System.out.println("o=" + o); } } }HashSetHashSet 实现了 Set 接口HashSet 底层实际上是是 HashMap不能有重复的元素,可以存放 null,但是只能有一个 nullHashSet 不保证元素是有序的,取决于 Hash 后,再确定索引的结果package com.bbedu.set_; import java.util.HashSet; public class HashSet01 { public static void main(String[] args) { HashSet hashSet = new HashSet(); System.out.println(hashSet.add("John")); System.out.println(hashSet.add("Lucy")); System.out.println(hashSet.add("John")); System.out.println(hashSet.add("Jack")); System.out.println(hashSet.add("Tim")); // 指定删除对象 hashSet.remove("John"); System.out.println("set=" + hashSet); hashSet = new HashSet(); System.out.println("set=" + hashSet); hashSet.add("lucy"); hashSet.add("lucy"); hashSet.add(new Dog("coco")); // OK hashSet.add(new Dog("coco")); // OK System.out.println("set=" + hashSet); // 看源码理解 // 不能添加重复元素的真正含义? hashSet.add(new String("bbchen")); // ok hashSet.add(new String("bbchen")); // no System.out.println("set=" + hashSet); } } class Dog { private String name; public Dog(String name) { this.name = name; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + '}'; } }HashSet 底层机制说明分析 HashSet 底层是 HashMap, HashMap 底层是(数组 + 链表 + 红黑树)数组+链表=邻接表,理解邻接表:package com.bbedu.set_; /** * 模拟邻接表 */ public class HashSetStructure { public static void main(String[] args) { // Node[] 数组 称为 表 Node[] table = new Node[16]; Node john = new Node("john", null); table[2] = john; Node jack = new Node("jack", null); john.next = jack; Node rose = new Node("Rose", null); jack.next = rose; } } class Node { Object item; Node next; public Node(Object item, Node next) { this.item = item; this.next = next; } }分析 HashSet 的添加元素底层是如何实现的同样,先结论,后Debug源码分析:初始化HashSet()/** * Constructs a new, empty set; the backing {@code HashMap} instance has * default initial capacity (16) and load factor (0.75). */ public HashSet() { map = new HashMap<>(); }add()/** * Adds the specified element to this set if it is not already present. * More formally, adds the specified element {@code e} to this set if * this set contains no element {@code e2} such that * {@code Objects.equals(e, e2)}. * If this set already contains the element, the call leaves the set * unchanged and returns {@code false}. * * @param e element to be added to this set * @return {@code true} if this set did not already contain the specified * element */ public boolean add(E e) { return map.put(e, PRESENT)==null; }put(),先执行 hash(key),得到对应的 hash 值,并不直接是 hashCode()/** * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for the key, the old * value is replaced. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with {@code key}, or * {@code null} if there was no mapping for {@code key}. * (A {@code null} return can also indicate that the map * previously associated {@code null} with {@code key}.) */ public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }hash()/** * Computes key.hashCode() and spreads (XORs) higher bits of hash * to lower. Because the table uses power-of-two masking, sets of * hashes that vary only in bits above the current mask will * always collide. (Among known examples are sets of Float keys * holding consecutive whole numbers in small tables.) So we * apply a transform that spreads the impact of higher bits * downward. There is a tradeoff between speed, utility, and * quality of bit-spreading. Because many common sets of hashes * are already reasonably distributed (so don't benefit from * spreading), and because we use trees to handle large sets of * collisions in bins, we just XOR some shifted bits in the * cheapest possible way to reduce systematic lossage, as well as * to incorporate impact of the highest bits that would otherwise * never be used in index calculations because of table bounds. */ static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }*putVal,核心代码!!!/** * Implements Map.put and related methods. * * @param hash hash for key * @param key the key * @param value the value to put * @param onlyIfAbsent if true, don't change existing value * @param evict if false, the table is in creation mode. * @return previous value, or null if none */ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; K k; if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }练习package com.bbedu.set_; import java.util.HashSet; import java.util.Iterator; import java.util.Objects; @SuppressWarnings({"all"}) public class HashSetExercise { public static void main(String[] args) { HashSet hashSet = new HashSet(); hashSet.add(new Employee("Jack", 20)); hashSet.add(new Employee("Mary", 18)); hashSet.add(new Employee("Jack", 20)); Iterator iterator = hashSet.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println("next=" + next); } } } @SuppressWarnings({"all"}) class Employee { private String name; private int age; public Employee(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Employee employee = (Employee) o; return age == employee.age && Objects.equals(name, employee.name); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", age=" + age + '}'; } }package com.bbedu.set_; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Objects; public class HashSetExercise02 { public static void main(String[] args) { HashSet hashSet = new HashSet(); hashSet.add(new Employee02("Tim", 20000, new MyDate(1990, 1, 1))); hashSet.add(new Employee02("Rock", 15000, new MyDate(1998, 4, 29))); hashSet.add(new Employee02("Tim", 23333, new MyDate(1990, 1, 1))); Iterator iterator = hashSet.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println("next=" + next); } } } class Employee02{ private String name; private double sal; private MyDate birthday; public Employee02(String name, double sal, MyDate birthday) { this.name = name; this.sal = sal; this.birthday = birthday; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public MyDate getBirthday() { return birthday; } public void setBirthday(MyDate birthday) { this.birthday = birthday; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Employee02 that = (Employee02) o; return Objects.equals(name, that.name) && Objects.equals(birthday, that.birthday); } @Override public int hashCode() { return Objects.hash(name, birthday); } @Override public String toString() { return "Employee02{" + "name='" + name + '\'' + ", sal=" + sal + ", birthday=" + birthday + '}'; } } class MyDate { private int year; private int month; private int day; public MyDate(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MyDate myDate = (MyDate) o; return year == myDate.year && month == myDate.month && day == myDate.day; } @Override public int hashCode() { return Objects.hash(year, month, day); } @Override public String toString() { return "MyDate{" + "year=" + year + ", month=" + month + ", day=" + day + '}'; } }LinkedHashSetLinkedHashSet 是 HashSet 的子类LinkedHashSet 底层是一个 LinkedHashMap,底层维护了一个 数组 + 双向链表LiniedHashSet 根据元素的 hashCode 值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的LinkedHashSet 不允许添加重复元素Map 接口Map 与 Collection 并列存在,用于保存具有映射关系的数据:Key-Value (双列元素)Map 中的 key 和 value 可以是任何引用类型的数据,会封装到 HashMap$Node 对象中Map 中的 key不允许重复,当有相同的 key 时,相当于替换Map 中的 value 可以重复key 和 value 都可以为 null,但 key 只能有一个 null,而 value 可以有多个 null常用 String 类来做 key,别的引用类型同样可以key 和 value 存在单向一对一关系(满射关系,即一种映射)常用方法六种遍历方法:package com.bbedu.map_; import java.util.*; public class MapFor { public static void main(String[] args) { HashMap hashMap = new HashMap(); hashMap.put("刘慈欣", "三体"); hashMap.put("张爱玲", "倾城之恋"); hashMap.put("萧红", "呼兰河传"); hashMap.put("托尔斯泰", "复活"); hashMap.put("史铁生", "我与地坛"); // 第一组 Set set = hashMap.keySet(); System.out.println("===增强for==="); for (Object o : set) { System.out.println(o + "-" + hashMap.get(o)); } System.out.println("===迭代器==="); Iterator iterator = set.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println(next + "-" + hashMap.get(next)); } // 第二组 Collection values = hashMap.values(); System.out.println("===取value==="); for (Object value : values) { System.out.println(value); } System.out.println("===迭代器==="); Iterator iterator1 = values.iterator(); while (iterator1.hasNext()) { Object next = iterator1.next(); System.out.println(next); } // 第三组 Set set1 = hashMap.entrySet(); System.out.println("===增强for==="); for (Object o : set1) { Map.Entry o1 = (Map.Entry) o; System.out.println(o1.getKey() + "-" + o1.getValue()); } System.out.println("===迭代器==="); Iterator iterator2 = set1.iterator(); while (iterator2.hasNext()) { Object next = iterator2.next(); Map.Entry next1 = (Map.Entry) next; System.out.println(next1.getKey() + "-" + next1.getValue()); } } } 练习package com.bbedu.map_; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class MapExercise { public static void main(String[] args) { HashMap<Integer,Employee> map = new HashMap(); Employee tom = new Employee("Tom", 20000, 1); Employee bob = new Employee("Bob", 15000, 2); Employee sam = new Employee("Sam", 19000, 3); map.put(tom.getId(), tom); map.put(bob.getId(), bob); map.put(sam.getId(), sam); System.out.println("===方式1==="); Set set = map.keySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); Employee employee = (Employee) map.get(next); if(employee.getSal() > 18000){ System.out.println(employee); } } System.out.println("===方式2==="); Set set1 = map.entrySet(); for (Object o : set1) { Map.Entry o1 = (Map.Entry) o; Employee value = (Employee) o1.getValue(); if(value.getSal() > 18000){ System.out.println(value); } } } } class Employee { private String name; private double sal; private int id; public Employee(String name, double sal, int id) { this.name = name; this.sal = sal; this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", sal=" + sal + ", id=" + id + '}'; } }HashMap底层机制及源码分析先结论:Hashtable存放的元素是键值对,即 K-VHashtable 的键和值都不能为null,否则会抛出 NullPointerExceptionHashtable 使用的方法基本上和 HashMap一样Hashtable 是线程安全的,HashMap 是线程不安全的扩容机制Hashtable 和 HashMap 对比PropertiesProperties 类继承自 Hashtable 类并且实现了 Map 接口,也是使用一种键值对的形式来保存数据它的特点和 Hashtable 类似Properties 还可以用于 从 xxx.properties 文件中加载数据到Properties 类对象,并进行读取和修改开发中如何选择集合实现类TreeSetTreeMapTreeMap 是 TreeSet 的底层Collections 工具类常用方法package com.bbedu.collections_; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class Collections_ { public static void main(String[] args) { // ArrayList 集合,用于测试 ArrayList list = new ArrayList(); list.add("tom"); list.add("jack"); list.add("sam"); list.add("mike"); list.add("smith"); System.out.println(list); System.out.println("===reverse==="); Collections.reverse(list); System.out.println(list); System.out.println("===shuffle==="); for (int i = 0; i < 5; i++) { Collections.shuffle(list); System.out.println(list); } System.out.println("===sort===="); Collections.sort(list); System.out.println(list); System.out.println("===自定义sort==="); Collections.sort(list, new Comparator<>() { @Override public int compare(Object o1, Object o2) { if(o1 instanceof String && o2 instanceof String){ return ((String) o1).length() - ((String) o2).length(); } return 0; } }); System.out.println(list); System.out.println("===swap==="); Collections.swap(list,0, 1); System.out.println(list); System.out.println("===max==="); System.out.println(Collections.max(list)); System.out.println("===自定义max==="); Object max = Collections.max(list, new Comparator() { @Override public int compare(Object o1, Object o2) { return ((String) o1).length() - ((String) o2).length(); } }); System.out.println(max); System.out.println("===frequency==="); System.out.println(Collections.frequency(list, "tom")); System.out.println("===copy==="); ArrayList dest = new ArrayList(); // 需要先给 dest 赋值,大小和 list相同 for (int i = 0; i < list.size(); i++) { dest.add(""); } Collections.copy(dest, list); System.out.println(dest); System.out.println("===replaceAll==="); Collections.replaceAll(list, "tom", "汤姆"); System.out.println(list); } }本章作业package com.bbedu.homework; import java.util.ArrayList; @SuppressWarnings({"all"}) public class Homework01 { public static void main(String[] args) { ArrayList arrayList = new ArrayList(); arrayList.add(new News("广东中山发现8例无症状感染者,均在隔离管控的密接人员中发现")); arrayList.add(new News("经济衰退阴云笼罩 惠誉下调美国2023年GDP增速预期")); for (int i = arrayList.size() - 1; i >= 0; i--) { News news = (News) arrayList.get(i); String s = processTitle(news.getTitle()); System.out.println(s); } } public static String processTitle(String title) { if (title == null) { return ""; } if (title.length() > 15){ return title.substring(0, 15) + "..."; }else{ return title; } } } class News { private String title; private String content; public News(String title) { this.title = title; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "News{" + "title='" + title + '\'' + '}'; } }package com.bbedu.homework; import java.util.ArrayList; public class Homework02 { public static void main(String[] args) { Car car1 = new Car("宝马", 300000); Car car2 = new Car("奔驰", 400000); Car car3 = new Car("宾利", 500000); ArrayList<Car> cars = new ArrayList<>(); cars.add(car1); cars.add(car2); cars.add(car3); System.out.println(cars); System.out.println("===增强for==="); for (Car car : cars) { System.out.println(car); } cars.remove(car3); System.out.println(cars); System.out.println(cars.contains(car3)); System.out.println(cars.isEmpty()); cars.clear(); System.out.println(cars); cars.add(car1); cars.add(car2); cars.add(car3); ArrayList<Car> cars1 = new ArrayList<>(); cars1.addAll(cars); System.out.println(cars1); System.out.println(cars1.containsAll(cars)); cars1.removeAll(cars); System.out.println(cars1); } } class Car { private String name; private double price; public Car(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Car{" + "name='" + name + '\'' + ", price=" + price + '}'; } }package com.bbedu.homework; import java.util.Collection; import java.util.HashMap; import java.util.Set; public class Homework03 { public static void main(String[] args) { HashMap hashMap = new HashMap(); hashMap.put("jack", 650); hashMap.put("tom", 1200); hashMap.put("smith", 2900); printAll(hashMap); System.out.println("===修改jack工资==="); hashMap.replace("jack", 2600); printAll(hashMap); System.out.println("===所有人工资+100==="); Set set = hashMap.keySet(); for (Object o : set) { hashMap.put(o, (Integer) hashMap.get(o) + 100); } printAll(hashMap); } public static void printAll(HashMap hashMap){ Set set = hashMap.keySet(); for (Object o : set) { System.out.println(o + "-" + hashMap.get(o)); } } public static void printAllSal(HashMap hashMap){ Set set = hashMap.keySet(); for (Object o : set) { System.out.println(hashMap.get(o)); } } }package com.bbedu.homework; import java.util.TreeSet; public class Homework05 { public static void main(String[] args) { TreeSet treeSet = new TreeSet(); treeSet.add(new Person()); treeSet.add(new Person()); treeSet.add(new Person()); treeSet.add(new Person()); treeSet.add(new Person()); treeSet.add(new Person()); System.out.println(treeSet); } } class Person implements Comparable{ @Override public int compareTo(Object o) { return 0; } }输出[Person2{id=1002, name='BB'}, Person2{id=1001, name='CC'}] [Person2{id=1002, name='BB'}, Person2{id=1001, name='CC'}, Person2{id=1001, name='CC'}] [Person2{id=1002, name='BB'}, Person2{id=1001, name='CC'}, Person2{id=1001, name='CC'}, Person2{id=1001, name='AA'}]
2023年02月26日
93 阅读
0 评论
0 点赞
2023-02-26
Chapter13_常用类
常用类本章内容包装类 Wrapper针对八种基本数据类型相应的引用类型——包装类有了类的特点,就可以调用类中的方法包装类和基本数据类型的转换jdk5 前的手动装箱和拆箱方式,装箱:基本类型 -> 包装类型,反正为拆箱jdk5 以后(含 jdk5)的自动装箱和拆箱方式自动装箱底层调用的是 valueOf 方法,比如 Integer.valueOf()package com.bbedu.wrapper; public class Integer01 { public static void main(String[] args) { // 演示 in Integer 的装箱和拆箱 // jdk5 之前手动 int n1 = 100; Integer integer = new Integer(n1); Integer integer1 = Integer.valueOf(n1); int i = integer.intValue(); // jdk5 后自动装箱拆箱 int n2 = 500; Integer integer2 = n2; // 底层是Integer.valueOf(n2) int n3 = integer2; // 底层是intValue()方法 Object obj1 = true ? new Integer(1) : new Double(2.0); System.out.println(obj1); } }包装类和 String 类的转换package com.bbedu.wrapper; public class WrapperVSString { public static void main(String[] args) { Integer i = 100; // Integer -> String // 方式1 String str1 = i + ""; // 方式2 String str2 = i.toString(); // 方式3 String str3 = String.valueOf(i); // String -> Integer String str4 = "12345"; // 方式1 Integer i2 = Integer.parseInt(str4); // 使用到自动装箱 // 方式2 Integer i3 = new Integer(str4); // 构造器 } }包装类的常用方法很多,使用时查阅即可Integer 细节falsetruefalse此处关键词:IntegerCacheString 类String 对象用于保存字符串,也就是一组字符序列字符串常量对象是用双引号括起的字符序列,例如:"你好","Hello",”5.21”等字符串的字符使用Unicode字符编码,一个字符占两个字节String 类有很多构造器,构造器重载:常用的有:String s2 = new String(String original);String s3 = new String(char[] a);String s4 = new String(char[] a,int startIndex,int count);String s5 = new String(byte[] b);String 类实现了 Serializable 接口,可以串行化,可以在网络传输实现了 Comparable 接口,可以相互比较大小String 是 final 类,不能被继承String 有一个 private final char value[]; 用于存放字符串内容,一定要注意,value 是一个 final 类型,不可修改(即 value 不能指向新的地址,但是单个字符的内容可以变化)创建 String 对象的两种方式方式一:直接赋值: String s = "bbedu"方式二:调用构造器:String s = new String("bbedu");区别方式一:先从常量池查看是否有"bbedu"数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s 最终指向的是常量池的空间地址方式二:先在堆中创建空间,里面维护了 value 属性,指向常量池的bbedu空间,如果常量池没有"bbedu",重新创建,如果有直接通过 value 指向,最终指向的是堆中的空间地址练习T F T Fb.intern() 方法最终返回的是常量池的地址F T T FT T T F三个对象:如图所示T T输出:hsp and havaString 类的常用方法String 类是保存字符串常量的,每次更新都需要重新开辟空间,效率较低,因此 java 设计者还提供了 StringBuilder 和 StringBuffer 来增强 String 的功能,并提高效率。package com.bbedu.string_; public class StringMethod01 { public static void main(String[] args) { // 1.equals String str1 = "hello"; String str2 = "Hello"; System.out.println(str1.equals(str2)); // false // 2. equalsIgnoreCase String username = "John"; if("john".equalsIgnoreCase(username)){ System.out.println("Success"); }else { System.out.println("Failure"); } // 3.length System.out.println("bbchen".length()); // 4.indexOf String s1 = "we@th@er"; System.out.println(s1.indexOf('@')); System.out.println(s1.indexOf("we")); System.out.println(s1.indexOf('#')); // 5.lastIndexOf System.out.println(s1.lastIndexOf('@')); System.out.println(s1.lastIndexOf('#')); // 6.substring String name = "hello,world"; System.out.println(name.substring(6)); System.out.println(name.substring(0, 5)); } }package com.bbedu.string_; public class StringMethod02 { public static void main(String[] args) { // 1.toUpperCase String s = "hello"; System.out.println(s.toUpperCase()); // 2.toLowerCase System.out.println(s.toLowerCase()); // 3.concat String s1 = ",world"; System.out.println(s.concat(s1)); // 4.replace String str = "bb want to be Java developer"; System.out.println(str.replace("Java", "Python")); System.out.println(str); // 5.split String poem = "锄禾日当午,汗滴禾下土"; String[] split = poem.split(","); for (String value : split) { System.out.println(value); } // 6.toCharArray String s2 = "happy"; char[] chs = s2.toCharArray(); for (char ch : chs) { System.out.println(ch); } // 7.compareTo String a = "jr"; String b = "jack"; System.out.println(a.compareTo(b)); System.out.println('r' - 'a'); // 8.format String name = "john"; String age = "10"; double score = 84.5 / 3; char gender = '男'; String formatStr = "我的名字是%s, 今年%d岁, 得分为%.2f, 性别为%c"; String info = String.format(formatStr, name, Integer.parseInt(age), score, gender); System.out.println(info); } }StringBuffer 类java.lang.StringBuffer 代表可变的字符序列,可以对字符串内容进行增删很多方法和 String 相同,但 StringBuffer 是可变长度的StringBuffer 是一个容器String vs StringBufferString 保存的是字符串常量,里面的值不能更改,每次 String 类的更新实际上就是更改地址,效率较低 //private final byte[] value;StringBuffer 保存的是字符串变量,里面的值可以更改,每次StringBuffer 的更新实际上可以更新内容,不用每次更新地址,效率较高 //byte[] value;String 和 StringBuffer 互相转换package com.bbedu.stringbuffer_; public class StringBuffer01 { public static void main(String[] args) { String str = "hello tim"; // String -> StringBuffer // 方式1 StringBuffer stringBuffer1 = new StringBuffer(str); // 方式2 StringBuffer stringBuffer = new StringBuffer("hello"); stringBuffer = stringBuffer.append(str); // StringBuffer -> String StringBuffer bbchen = new StringBuffer("bbchen"); // 方式1.toString String s = bbchen.toString(); // 方式2.构造器 String s1 = new String(bbchen); } }常见方法package com.bbedu.stringbuffer_; public class StingBufferMethod { public static void main(String[] args) { StringBuffer hello = new StringBuffer("hello"); // 1.append hello.append(','); hello.append("world"); System.out.println(hello); // 2.delete hello.delete(2, 4); // 删除下标[2,4)的字符 System.out.println(hello); // 3.replace hello.replace(4, 9, "bbchen"); System.out.println(hello); // 4.indexOf int index = hello.indexOf("e"); System.out.println(index); // 5.insert hello.insert(10, "gogogo"); System.out.println(hello); // 6.length System.out.println(hello.length()); } }StringBuilder 类StringBuilder 继承 AbstractStringBuilder 类实现了 Serializable,说明 StringBuilder 对象是可以串行化StringBuilder 是 final 类,不能被继承StringBuilder 对象字符序列仍然是存放在其父类 AbstractStringBuilder 的 byte[] value,因此字符序列是在堆中StringBuilder 的方法,没有做互斥的处理,即没有 synchronized 关键字,因此在单线程的情况下使用 StringBuilderString, StringBuffer 和 StringBuilder 的比较StringBuilder 和 StriBuffer 非常相似,均代表可变的字符序列,而且方法也一样String: 不可变字符序列,效率低,但是复用率高StringBuffer: 可变字符序列、效率较高、线程安全StringBuilder: 可变字符序列、效率最高、线程不安全String 使用说明:如果我们对 String 做大量修改,不要使用 String结论如果字符串存在大量的修改操作,一般使用StringBuffer 或StringBuilder如果字符串存在大量的修改操作,并在单线程的情况,使用 StringBuilder如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer如果我们字符串很少修改,被多个对象引用,使用String, 比如配置信息等StringBuilder的方法使用和 StringBuffer一样,不再赘述Math 类package com.bbedu.math_; import java.io.FilterOutputStream; public class MathMethod { public static void main(String[] args) { // 5.round long round = Math.round(5.51); System.out.println(round); // 6.sqrt double sqrt = Math.sqrt(9); System.out.println(sqrt); // 7.random 返回 [0, 1) 直接的随机小数 for (int i = 0; i < 10; i++) { //返回 [2, 7] 的随机整数 System.out.println((int)(Math.random() * 6 + 2)); } // max, min int min = Math.min(1, 9); int max = Math.max(4, 20); System.out.println(min); System.out.println(max); } }Arrays 类Comparator原理:while (left < right) { int mid = (left + right) >>> 1; if (c.compare(pivot, a[mid]) < 0) right = mid; else left = mid + 1; }package com.bbedu.arrays_; import java.util.Arrays; import java.util.Comparator; public class ArrayMethod01 { public static void main(String[] args) { // toString Integer[] integers = {1, 20, 90}; System.out.println(Arrays.toString(integers)); // sort Integer[] arr = {1, -1, 31, 3, 2, 53, 9, 20}; Arrays.sort(arr); // 默认排序方法 // 定制排序, 体现接口编程的方式 Arrays.sort(arr, new Comparator<Integer>() { // 匿名内部类 @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } }); System.out.println("Sorted:"); System.out.println(Arrays.toString(arr)); } }package com.bbedu.arrays_; import java.util.Arrays; import java.util.Comparator; public class ArraysSortCustom { public static void main(String[] args) { int[] arr = {0, -3, 20, 14, 23, 43, 21}; System.out.println(Arrays.toString(arr)); bubble02(arr, new Comparator() { @Override public int compare(Object o1, Object o2) { int i1 = (Integer) o1; int i2 = (Integer) o2; return i2 - i1; } }); System.out.println(Arrays.toString(arr)); } // 使用冒泡排序 public static void bubble01(int[] arr){ int temp = 0; for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - i - 1; j++) { if(arr[j] > arr[j + 1]){ temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } // 结合冒泡 + 定制 public static void bubble02(int[] arr, Comparator c){ int temp = 0; for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - i - 1; j++) { // c if(c.compare(arr[j], arr[j + 1]) > 0){ temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }package com.bbedu.arrays_; import java.util.Arrays; import java.util.List; public class ArraysMethod02 { public static void main(String[] args) { Integer[] arr = {1, 3, 5, 23, 100, 854, 1145}; // 二分查找,要求数组有序 // 不存在返回 return -(low + 1); // key not found. int index = Arrays.binarySearch(arr, -23); System.out.println(index); // copyOf // 拷贝长度 > arr.length ,在数组后加 null Integer[] newArr = Arrays.copyOf(arr, arr.length + 1); System.out.println(Arrays.toString(newArr)); // fill 数组填充 Integer[] num = new Integer[]{9, 3, 2}; Arrays.fill(num, 99); System.out.println(Arrays.toString(num)); // equals 比较两数组是否完全一样,区分顺序 Integer[] arr2 = {3, 1, 5, 23, 100, 854, 1145}; boolean equals = Arrays.equals(arr, arr2); System.out.println(equals); // asList List<Integer> integers = Arrays.asList(2, 3, 4, 5, 6, 1); System.out.println(integers); System.out.println(integers.getClass()); } }练习package com.bbedu.arrays_; import java.util.Comparator; @SuppressWarnings("all") public class ArraysExercise { public static void main(String[] args) { Book[] books = new Book[4]; books[0] = new Book("红楼梦", 100); books[1] = new Book("金瓶梅", 90); books[2] = new Book("三体", 60); books[3] = new Book("毛泽东选集", 300); for (int i = 0; i < books.length; i++) { System.out.println(books[i].toString()); } // 按价格 // Book.sort(books, new Comparator() { // @Override // public int compare(Object o1, Object o2) { // Book i1 = (Book) o1; // Book i2 = (Book) o2; // // // 返回类型不一致,进行转换 // double priceVal = i2.getPrice() - i1.getPrice(); // if(priceVal > 0) { // return -1; // } else if (priceVal < 0) { // return 1; // }else { // return 0; // } // } // }); // 按照书名从长到短 Book.sort(books, new Comparator() { @Override public int compare(Object o1, Object o2) { Book i1 = (Book) o1; Book i2 = (Book) o2; return i1.getName().length() - i2.getName().length(); } }); System.out.println("====排序后===="); for (int i = 0; i < books.length; i++) { System.out.println(books[i].toString()); } } } @SuppressWarnings("all") class Book { private String name; private double price; public Book(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", price=" + price + '}'; } public static void sort(Book[] b, Comparator c){ Book book = null; for (int i = 0; i < b.length - 1; i++) { for (int j = 0; j < b.length - i - 1; j++) { // 定义接口, 根据价格排序 if(c.compare(b[j], b[j + 1]) < 0){ book = b[j]; b[j] = b[j + 1]; b[j + 1] = book; } } } } }System 类package com.bbedu.system_; import java.util.Arrays; public class System_ { public static void main(String[] args) { // // exit 0为正常状态 // System.out.println("ok1"); // System.exit(0); // System.out.println("ok2"); // arraycopy // * @param src the source array. // * @param srcPos starting position in the source array. // * @param dest the destination array. // * @param destPos starting position in the destination data. // * @param length the number of array elements to be copied. int[] arr1 = {1, 2, 3}; int[] arr2 = new int[3]; System.arraycopy(arr1, 0, arr2, 1, 2); System.out.println(Arrays.toString(arr2)); System.out.println(System.currentTimeMillis()); } }BigInteger 和 BigDecimal 类package com.bbedu.bignum; import java.math.BigInteger; public class BigInteger_ { public static void main(String[] args) { // 数字太大,需要使用 BigInteger 类 // long l = 233333333333333333333333333333L; BigInteger bigInteger = new BigInteger("23333333333333333333333333"); BigInteger bigInteger1 = new BigInteger("1000000"); System.out.println(bigInteger); // 加减乘除使用对应方法 System.out.println(bigInteger.add(bigInteger1)); System.out.println(bigInteger.subtract(bigInteger1)); System.out.println(bigInteger.divide(bigInteger1)); System.out.println(bigInteger.multiply(bigInteger1)); } }package com.bbedu.bignum; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; public class BigDecimal_ { public static void main(String[] args) { double d = 1111.1111111111119999999999999999; System.out.println(d); // 需要保存精度很高的数时,使用 BigDecimal BigDecimal bigDecimal = new BigDecimal("1111.1111111111119999999999999999"); System.out.println(bigDecimal); // 加减乘除需要使用特定方法 BigDecimal bigDecimal1 = new BigDecimal("100.9999999999"); System.out.println(bigDecimal.add(bigDecimal1)); System.out.println(bigDecimal.subtract(bigDecimal1)); System.out.println(bigDecimal.divide(bigDecimal1, RoundingMode.CEILING)); //可能异常:ArithmeticException: Non-terminating decimal System.out.println(bigDecimal.multiply(bigDecimal1)); } }日期类package com.bbedu.date_; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class Date01 { public static void main(String[] args) throws ParseException { // 过去当前系统时间,通常需要格式转换 Date d1 = new Date(); System.out.println(d1); System.out.println(d1.getTime()); Date date = new Date(92345678); System.out.println(date); // 参见手册 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E"); String format = simpleDateFormat.format(d1); System.out.println(format); // 字符串转 Date String s = "2022年10月13日 02:33:02 周四"; Date parse = simpleDateFormat.parse(s); System.out.println(parse); } }package com.bbedu.date_; import java.util.Calendar; public class Calendar_ { public static void main(String[] args) { Calendar c = Calendar.getInstance(); System.out.println("c=" + c); // 需要自己组合: System.out.println("年:" + c.get(Calendar.YEAR)); System.out.println("月:" + (c.get(Calendar.MONTH)+1)); // 月从0开始 System.out.println("日:" + c.get(Calendar.DAY_OF_MONTH)); } }package com.bbedu.date_; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; public class LocalDate_ { public static void main(String[] args) { // 第三代日期 LocalDateTime now = LocalDateTime.now(); System.out.println(now); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String format = dateTimeFormatter.format(now); System.out.println(format); System.out.println("年=" + now.getYear()); System.out.println("月=" + now.getMonthValue()); System.out.println("月=" + now.getMonth()); System.out.println("日=" + now.getDayOfMonth()); System.out.println("时=" + now.getHour()); System.out.println("分=" + now.getMinute()); System.out.println("秒=" + now.getSecond()); LocalDate now1 = LocalDate.now(); LocalTime now2 = LocalTime.now(); System.out.println(now1); System.out.println(now2); } }package com.bbedu.date_; import java.util.Date; import java.time.Instant; public class Instant_ { public static void main(String[] args) { Instant now = Instant.now(); System.out.println(now); // from 方法 将 Instant 转为 Date 对象 Date date = Date.from(now); System.out.println(date); // toInstant 方法将 Date 转为 Instant Instant instant = date.toInstant(); System.out.println(instant); } }使用时查看 API 即可本章作业package com.bbedu.homework; import java.util.Arrays; public class Homework01 { public static void main(String[] args) { String str = "abcdef"; System.out.println(reverse(str, 2, 4)); } public static String reverse(String str, int start, int end){ if(! (str != null && start >= 0 && end > start && end < str.length())){ throw new RuntimeException("参数不正确"); } char[] chars = str.toCharArray(); char temp = ' '; while (start < end){ temp = chars[start]; chars[start] = chars[end]; chars[end] = temp; start++; end--; } return Arrays.toString(chars); } }package com.bbedu.homework; public class Homework02 { public static void main(String[] args) { String name = "Tom"; String pwd = "123456"; String email = "tom@qq.com"; try { userRegister(name, pwd, email); System.out.println("注册成功"); }catch (Exception e){ System.out.println(e.getMessage()); } } public static void userRegister(String name, String pwd, String email){ int nameLength = name.length(); if(!(nameLength >= 2 && nameLength <= 4)){ throw new RuntimeException("用户名长度在[2, 4]"); } if(!(pwd.length() == 6 && isDigital(pwd))){ throw new RuntimeException("密码长度为6,且全部为数字"); } int i = email.indexOf('@'); int j = email.indexOf('.'); if(!( i > 0 && j > i)){ throw new RuntimeException("邮箱有误"); } } public static boolean isDigital(String str){ char[] chars = str.toCharArray(); for (int i = 0; i < chars.length; i++) { if(chars[i] < '0' || chars[i] > '9'){ return false; } } return true; } }package com.bbedu.homework; import java.util.Arrays; public class Homework03 { public static void main(String[] args) { System.out.println(nameFormat("Chen xue Bin")); System.out.println(nameFormat("William jefferson Clinton")); } public static String nameFormat(String name){ if(name == null){ System.out.println("不能为空"); return null; } String[] s = name.split(" "); if(s.length != 3){ System.out.println("输入格式不正确"); return null; } // StringBuffer stringBuffer = new StringBuffer(); // stringBuffer.append(s[0]); // stringBuffer.append(","); // stringBuffer.append(s[2]); // stringBuffer.append(" ."); // stringBuffer.append(s[1].toUpperCase().charAt(0)); // return stringBuffer.toString(); String format = String.format("%s,%s .%c", s[2], s[0], s[1].toUpperCase().charAt(0)); return format; } }
2023年02月26日
67 阅读
0 评论
0 点赞
2023-02-26
Chapter12_异常
异常 (Exception)本章内容异常基本介绍如果程序员认为一段代码可能出现异常/问题,可以使用 try-catch 异常处理机制来解决,从而保证程序的健壮性将该代码块 -> 选中 -> crtl + alt + t 快捷键 -> 选中 try-catchJava语言中,将程序执行中的不正常情况成为“异常”。(开发过程中的语法和逻辑错误不是异常)执行过程中所发生的异常可以分为两大类:Error:Java虚拟机无法解决的严重问题。如 JVM 系统内部错误、资源耗尽等严重情况Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以 使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等。Exception 又分为两大类:运行时异常(程序运行时发生的异常)编译时异常(编程时,编译器检查出的异常)*异常体系图小结:运行时异常,是编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该避免其出现的异常。java.lang.RuntimeException类以及它的子类都是运行时异常对于运行时异常,可以不做处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响编译时异常,是编译器要求必须处置的异常常见的运行时异常NullPointerException 空指针异常当应用程序试图再需要对象的地方使用 null 时,抛出该异常ArithmeticException 数学算数异常当出现异常的运算条件时,抛出此异常。例如“除以零”。ArrayIndexOutOfBoundsException 数组下标越界异常用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则为非法索引ClassCastException 类转换异常当试图将对象强制转换为不是实例的子类时,抛出该异常NumberFormatException 数字格式异常当应用程序试图将字符串转化成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常异常处理机制JVM 的处理方式:1. 输出异常信息 2. 退出程序如果程序员没有显式地处理异常,默认 throws细节如果 try 代码块有可能有多个异常,可以使用多个 catch 分别捕获不同的异常,相应处理要求子类异常写在前面,父类异常写在后面可以直接进行 try-finally 配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉。应用场景:执行一段代码,不管是否发生异常,都必须执行某个业务逻辑练习输出:4输出:4输出:i=43小结如果没有出现异常,则执行 try 中的所有语句,不执行 catch 块中语句,如果有 finally,最后还需要执行 finally 里面的语句如果出现异常,则 try 块中异常发生后,try 块剩下的语句不再执行。将执行 catch 块中的语句,如果有 finally,最后还需要执行 finally 里面的语句throws处理机制如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。细节对于编译异常,程序必须处理对于运行时异常,程序中如果没有处理,默认就是 throws 的方式处理子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出异常类型的子类型throws 和 try-catch 二选一自定义异常package com.bbedu.exception_; public class CustomException { public static void main(String[] args) { int age = 180; if (!(age >= 18 && age <= 120)){ throw new AgeException("年龄需要在 18-120 之间"); } System.out.println("正确"); } } class AgeException extends RuntimeException { public AgeException(String message) { super(message); } }一般情况下,我们自定义异常是继承 RuntimException,因为有默认的异常处理机制,比较方便throw 和 throws 的区别
2023年02月26日
41 阅读
0 评论
0 点赞
2023-02-26
Chapter11_枚举和注解
枚举和注解本章内容枚举(enumeration, 简写enum)枚举是一组常量的集合,属于一种特殊的类,里面只包含一组有限的特定的对象实现方式:自定义枚举类型package com.bbchen.enum_; public class Enumeration02 { public static void main(String[] args) { System.out.println(Season.SPRING); System.out.println(Season.SUMMER); System.out.println(Season.AUTUMN); System.out.println(Season.WINTER); } } // 演示自定义枚举实现 class Season { private String name; private String desc; public final static Season SPRING = new Season("春天", "温暖"); public final static Season SUMMER = new Season("夏天", "炎热"); public final static Season AUTUMN = new Season("秋天", "凉爽"); public final static Season WINTER = new Season("冬天", "寒冷"); // 1.构造器私有化,防止直接 new // 2.去掉 setter 方法,防止属性被修改 // 3.在 Season 内部,直接创建固定的对象 // 4.final static private Season(String name, String desc) { this.name = name; this.desc = desc; } public String getName() { return name; } public String getDesc() { return desc; } @Override public String toString() { return "Season{" + "name='" + name + '\'' + ", desc='" + desc + '\'' + '}'; } }使用 enum关键字 来实现package com.bbchen.enum_; public class Enumeration03 { public static void main(String[] args) { System.out.println(Season2.SPRING); System.out.println(Season2.SUMMER); System.out.println(Season2.AUTUMN); System.out.println(Season2.WINTER); } } // 演示 enum关键字 枚举实现 enum Season2 { // public final static Season2 SPRING = new Season2("春天", "温暖"); // public final static Season2 SUMMER = new Season2("夏天", "炎热"); // public final static Season2 AUTUMN = new Season2("秋天", "凉爽"); // public final static Season2 WINTER = new Season2("冬天", "寒冷"); // 如果使用 enum 来实现枚举类 // 1.使用 enum 替代 class // 2.使用 SPRING("春天", "温暖"); 代替 // public final static Season2 SPRING = new Season2("春天", "温暖"); // 3.如果有多个对象常量,使用 ,号间隔即可 // 4.要求将定义常量写在前面 SPRING("春天", "温暖"), SUMMER("夏天","炎热"), AUTUMN("秋天", "凉爽"), WINTER("冬天", "寒冷"); private String name; private String desc; private Season2(String name, String desc) { this.name = name; this.desc = desc; } public String getName() { return name; } public String getDesc() { return desc; } @Override public String toString() { return "Season{" + "name='" + name + '\'' + ", desc='" + desc + '\'' + '}'; } }注意事项当我们使用 enum关键字 来开发一个枚举类时,默认会继承 Enum 类,而且是一个 final 类,使用 javap 来证明使用 SPRING("春天", "温暖"); 代替 public final static Season2 SPRING = new Season2("春天", "温暖");无参构造器创建常量对象,则省略可以不写括号()当有多个枚举对象是,使用逗号间隔,最后一个以分号结尾枚举对象必须放在枚举类的最前面练习Enum 成员方法package com.bbchen.enum_; /** * 演示 Enum 类的各种方法,使用 Season2 演示 */ public class EnumMethod { public static void main(String[] args) { Season2 autumn = Season2.AUTUMN; // name() 输出枚举对象的名字 System.out.println(autumn.name()); // ordinal() 输出该枚举对象的次序/编号,从0开始 System.out.println(autumn.ordinal()); // values() 返回 Season2[], 含有定义的所有枚举 Season2[] values = Season2.values(); for (Season2 season: values) { System.out.println(season); } // valueOf() 将字符串转换成枚举对象,要求字符串必须为已有常量名 // 1.根据输入的 "AUTUMN" 到 Season2 的枚举对象去查找 // 2.如果找到,就返回该对象,如果没有则报错 System.out.println("autumn1 = " + Season2.valueOf("AUTUMN")); // compareTo() 将枚举对象的编号进行比较 // self.ordinal - other.ordinal // 调用元素编号 - 比较元素编号 System.out.println(Season2.AUTUMN.compareTo(Season2.SPRING)); } } 练习package com.bbchen.enum_; public class EnumExercise02 { public static void main(String[] args) { Week[] weeks = Week.values(); System.out.println("===所有星期的信息如下==="); for (Week week: weeks) { System.out.println(week); } } } enum Week { MONDAY("星期一"), TUESDAY("星期二"), WEDNESDAY("星期三"), THURSDAY("星期四"), FRIDAY("星期五"), SATURDAY("星期六"), SUNDAY("星期日"); private final String name; Week(String name) { this.name = name; } @Override public String toString() { return name; } }enum 实现接口使用 enum 关键字后,就不能在继承其他类了,因为 enum 会隐式继承 Enum,而 Java 是单继承制enum 实现的枚举类,仍然是一个类,所以还是可以实现接口的注解 (Annotation,了解即可)注解(Annotation)也被称为元数据(Metadata),用于修饰解释包、类、方法、属性、构造器、局部变量等数据信息。和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息。在 JavaSE 中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替 javaEE 旧版中所遗留的繁冗代码和 XML 配置等。Annotation三个基本的 Annotation:@Override: 限定某个方法,是重写父类方法,该注解只能用于方法@Deprecated: 用于表示某个程序元素(类,方法等)已经过时,即不再推荐使用,但是仍然可以使用@SuppressWarnings: 抑制编译器警告元注解
2023年02月26日
31 阅读
0 评论
0 点赞
1
...
3
4
5
...
7