Set
Set : 无序,不可重复 无序: 存放的顺序与内部真实存储对的顺序不一致 新增内容 : static <E> Set<E> of(E... elements) 返回包含任意数量元素的不可修改集。 遍历方式: foreach iterator
public class Class001_Set { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("zhangsan"); set.add("lisi"); set.add("wangwu"); set.add("wangwu"); set.add(null); System.out.println(set); //static <E> Set<E> of(E... elements) 返回包含任意数量元素的不可修改集。 System.out.println(Set.of(4,3,1,2,0)); //foreach for (String str:set){ System.out.println(str); } //iterator Iterator<String> it = set.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }
TreeSet
底层结构:红黑树(平衡二叉树)
特点:自动对数据做默认的升序排序
应用场景:需要对数据去重,并且对数据进行排序
遍历方式:
-
foreach
-
iterate
TreeSet对不同类型的数据,不能做默认的排序
public class Class002_TreeSet { public static void main(String[] args) { TreeSet<String> set = new TreeSet<>(); set.add("bc"); set.add("ac"); set.add("abc"); set.add("a"); set.add("ab"); set.add("b"); System.out.println(set); TreeSet<Integer> set2 = new TreeSet<>(); set2.add(8); set2.add(6); set2.add(3); set2.add(1); //E ceiling(E e) 返回此set中大于或等于给定元素的 null元素,如果没有这样的元素,则 null 。 System.out.println(set2.ceiling(3)); //E floor(E e) 返回此set中小于或等于给定元素的最大元素,如果没有这样的元素,则 null 。 System.out.println(set2.floor(5)); //E first() 返回此集合中当前的第一个(最低)元素。 //E last() 返回此集合中当前的最后一个(最高)元素。 System.out.println(set2.first()); //E higher(E e) 返回此集合中的最小元素严格大于给定元素,如果没有这样的元素,则 null 。 //E lower(E e) 返回此集合中的最大元素严格小于给定元素,如果没有这样的元素,则 null 。 System.out.println(set2.lower(3)); //E pollFirst() 检索并删除第一个(最低)元素,如果此组为空,则返回 null 。 //E pollLast() 检索并删除最后一个(最高)元素,如果此集合为空,则返回 null 。 System.out.println(set2); System.out.println(set2.pollFirst()); System.out.println(set2); } }
比较器:
-
内部比较器|自然排序:
实现Comparable<T>接口,重写compareTo(T o)方法,方法体中制定比较规则
-
外部比较器|自定义排序:
实现Comperator<T>接口,重写compare方法,方法体中制定比较规则
注意:
-
TreeSet去重、排序都根据比较规则实现
-
如果指定外部比较规则,使用外部比较规则,没有指定外部比较规则,使用内部比较规则,都不在,抛出类型转换异常ClassCastException
public class Class003_Compare { public static void main(String[] args) { //默认找存储数据的内部比较规则,自然排序方式: 1)检查Goods是否实现了Comparable接口 2)通过compareTo方法实现去重与排序 TreeSet<Goods> set = new TreeSet<>(); set.add(new Goods(103,"水杯")); set.add(new Goods(101,"茶杯")); set.add(new Goods(102,"保温杯")); set.add(new Goods(102,"玻璃杯")); System.out.println(set); //当前TreeSet集合,存储数据使用指定的外部比较规则,实参指定的比较规则 //TreeSet(Comparator<? super E> comparator) 构造一个新的空树集,根据指定的比较器进行排序。 TreeSet<Goods> set2 = new TreeSet<>(new Impl()); set2.add(new Goods(103,"水杯")); set2.add(new Goods(101,"茶杯")); set2.add(new Goods(102,"保温杯")); set2.add(new Goods(102,"玻璃杯")); System.out.println(set2); } } //定义一个Comparator接口实现类 class Impl implements Comparator<Goods>{ /* o1,o2 o1.compareTo(o2) 返回值: 0 ---> o1==o2 <0 ---> o1<o2 >0 ---> o1>02 */ @Override public int compare(Goods o1, Goods o2) { return o1.getId()-o2.getId(); } } class Goods implements Comparable<Goods>{ private int id; private String name; public Goods() { } public Goods(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Goods{" + "id=" + id + ", name='" + name + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Goods goods = (Goods) o; return id == goods.id && Objects.equals(name, goods.name); } /* 根据商品编号做默认升序排序 o1,o2 o1.compareTo(o2) 返回值: 0 ---> o1==o2 <0 ---> o1<o2 >0 ---> o1>02 eg : 商品o1 : 101 '水杯' 商品o2 : 102 '水杯' o1.compareTo(02) : return 101-102--> return -1; --> {o1,o2} o1.compareTo(02) : return 102-101--> return 1; --> {o2,o1} */ @Override public int compareTo(Goods o) { //this --> o1 //o --> o2 //return this.id-o.id; return o.id-this.id; } }
练习:
定义员工类,使用Arrays.sort方法对多个员工做根据薪资做升序排序
public class Class004_ArraysSort { public static void main(String[] args) { Employee[] arr = { new Employee("胡歌",20000), new Employee("彭于晏",19000), new Employee("吴彦祖",21000), new Employee("刘德华",30000), }; System.out.println(Arrays.toString(arr)); //Arrays.sort() 默认升序排序 Arrays.sort(arr); System.out.println(Arrays.toString(arr)); //static <T> void sort(T[] a, Comparator<? super T> c) 根据指定比较器引发的顺序对指定的对象数组进行排序。 /*Arrays.sort(arr,new Comparator<Employee>(){ @Override public int compare(Employee o1, Employee o2) { return Double.compare(o2.getSal(),o1.getSal()); } });*/ //lambda Arrays.sort(arr,(o1,o2)-> Double.compare(o2.getSal(),o1.getSal())); System.out.println(Arrays.toString(arr)); } } class Employee implements Comparable<Employee>{ private String username; private double sal; public Employee() { } public Employee(String username, double sal) { this.username = username; this.sal = sal; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } @Override public String toString() { return "Employee{" + "username='" + username + '\'' + ", sal=" + sal + '}'; } @Override public int hashCode() { return 0; } @Override public boolean equals(Object o) { return false; } @Override public int compareTo(Employee o) { return Double.compare(this.sal,o.sal); } }
HashSet
-
底层结构:哈希表(数组+链表+红黑树)
-
特点:查询增删效率高、去重、无序
-
应用场景:适合运用在去重、无序、查询增删效率较高的地方
-
存储JavaBean类型数据实现去重:
-
需要JavaBean进行重写equals与hashcode方法,需要根据对象的属性值进行判断|计算,不能根据对象地址
-
思考:重写hashcode与equals方法后
两个hashcode相等,equals就一定相等? 不一定
两个equals相等,hashcode就一定相等? 一定
public class Class005_HashSet { public static void main(String[] args) { System.out.println("你好".hashCode()); System.out.println(new Employee().hashCode()); System.out.println(new Employee().hashCode()); System.out.println(new Integer(123).hashCode()); //通过HashSet存储Javabean类型数据 : 实现正确存储,实现去重(逻辑认为: 所有成员变量值都想等就是一个对象,就应该实现去重) HashSet<Employee> set = new HashSet<>(); set.add(new Employee("张正阳",20000)); set.add(new Employee("朱宽喜",18000)); set.add(new Employee("王家奇",19000)); set.add(new Employee("王家奇",19000)); System.out.println(new Employee("王家奇",19000).hashCode()); System.out.println(new Employee("王家奇",19000).hashCode()); System.out.println(set); } }