Set
Set : 无序,不可重复 无序: 存放的顺序与内部真实存储对的顺序不一致 新增内容 : static
public class Class001_Set {
public static void main(String[] args) {
Set set = new HashSet<>();
set.add("zhangsan");
set.add("lisi");
set.add("wangwu");
set.add("wangwu");
set.add(null);
System.out.println(set);
//static Set of(E... elements) 返回包含任意数量元素的不可修改集。
System.out.println(Set.of(4,3,1,2,0));
//foreach
for (String str:set){
System.out.println(str);
}
//iterator
Iterator 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 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 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
接口,重写compareTo(T o)方法,方法体中制定比较规则 -
外部比较器|自定义排序:
实现Comperator
接口,重写compare方法,方法体中制定比较规则
注意:
-
TreeSet去重、排序都根据比较规则实现
-
如果指定外部比较规则,使用外部比较规则,没有指定外部比较规则,使用内部比较规则,都不在,抛出类型转换异常ClassCastException
public class Class003_Compare {
public static void main(String[] args) {
//默认找存储数据的内部比较规则,自然排序方式: 1)检查Goods是否实现了Comparable接口 2)通过compareTo方法实现去重与排序
TreeSet 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 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{
@Override
public int compare(Goods o1, Goods o2) {
return o1.getId()-o2.getId();
}
}
class Goods implements Comparable{
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);
}
@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 void sort(T[] a, Comparator super T> c) 根据指定比较器引发的顺序对指定的对象数组进行排序。
//lambda
Arrays.sort(arr,(o1,o2)-> Double.compare(o2.getSal(),o1.getSal()));
System.out.println(Arrays.toString(arr));
}
}
class Employee implements Comparable{
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 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);
}
}



