Java学习笔记(十八):Set集合
Set集合
Set集合与List不同的是,Set集合中的元素不能重复。
HashSet集合
一、特点:
- 底层数据结构为哈希表(HashMap的实例),初始容量为16,加载因子0.75,元素无序(即数据的存储顺序不一致);
- 不允许重复元素;
- 线程不安全,效率高。
二、HashSet保证元素唯一性的原理
当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。
假如有两个对象算出的hashCode值相等,则会调用equals( )方法,去比较两个对象的地址值是否相等,如果相等则不储存,不相等则将后一个对象存储在链表的下一个结点。
**为了保证HashSet元素的唯一性,需要重写HashCode( )和equals( )方法。**如在学生类中进行重写:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
//IDEA重写时,调用一个工具 Objects.hash(name, age); 根据成员变量,算出一个整数值
return Objects.hash(name, age);
}
对于无序的HashSet,遍历时有两种方法:
-
增强for循环;
-
Object构造器。
LinkedHashSet
特点:
- 底层结构为链表+哈希表。链表保证元素有序,哈希表保证元素唯一;
- 元素有序唯一;
- 线程不安全效率高。
TreeSet
一、特点
- 底层数据结构为二叉树;
- 元素唯一,并且可以对元素进行排序;
二、排序方式
排序方式取决于构造方法。
-
自然排序(空参)
使用空参构造时,用的就是自然排序。使用自然排序时,要求元素必须实现一个Comparable接口,并且重写这个接口中的Compara To( )方法(否则会报错)。根据这个方法的返回值的正、负、零来判断是否将其放入和确定元素在二叉树中存放的位置。
-
比较器排序
使用有参构造时,用的就是比较器排序。使用自然排序时,要求元素必须传入一个实现比较器Comparator接口的子类对象,并且重写这个接口中的compara( )方法(否则会报错)。根据这个方法的返回值的正、负、零来判断是否将其放入和确定元素在二叉树中存放的位置。
比较器Comparator不仅可以用于TreeSet集合,也可以在其他类中使用,比如ArrayList集合中的Sort方法,用以改变排序方式。
如使用匿名对象重写compara( )方法:
TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num=s1.getAge()-s2.getAge();
//年龄一样并不能说明是同一个对象,还得比较姓名是否一样
int num2=num==0?s1.getName().compareTo(s2.getName()):num;
return -num2;
}
});