Set系列集合概述
Set系列集合特点
- 无序:存取顺序不一致
- 不重复:可以去除重复
- 无索引:没有带索引的方法,所以不能使用普通的for循环遍历,也不能通过索引来获取元素
Set集合实现类特点
- HashSet:无序 不重复 无索引
- LinkedHashSet:有序 不重复 无索引
- TreeSet:排序 不重复 无索引
HashSet元素的无序的底层原理:哈希表
HashSet底层原理
- HashSet集合底层采取哈希表存储的数据
- 哈希表是一种对于增删改查数据性能都较好的结构
哈希表的组成
- JDK8之前,底层使用数组+链表组成
- JDK8之后,底层采用数组+链表+红黑树组成
哈希值
- JDK根据对象的地址,按照某种规则算出来的int类型的数值
Object类的API
- public int hashCode():返回对象的哈希值
对象的哈希值特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的
HashSet1.7版本原理解析:数组+链表+(结合哈希算法)
- 创建一个默认长度16的数组,数组名table
- 根据元素的哈希值跟数组的长度求余计算出应存入的位置(哈希算法)
- 判断当前位置是否为null,如果是null直接存入
- 如果位置不为null,表示有元素,则调用equals方法比较
- 如果一样,则不存,如果不一样,则存入数组
- JDK7 新元素占老元素位置,指向老元素
- JDK8 中新元素挂在老元素下面
结论:哈希表是一种对于增删改查数据性能都比较好的结构
JDK1.8 版本HashSet原理解析
- 底层结构:哈希表(数组+链表+红黑树的结合体)
- 当挂在元素下面的数据过多时,查询性能降低,从JDK8开始后,当链表长度超过8的时候,自动转换为红黑树
结论:JDK8开始后,哈希表对于红黑树的引入进一步提高了操作数据的性能
哈希表的详细流程
- 创建一个默认长度为16,默认加载因子为0.75的数组,数组名为table
- 根据元素的哈希值跟数组的长度计算出应该存入的位置
- 判断当前位置是否为null,如果是null直接存入,如果位置不为null,表示有元素,则调用equals方法比较属性值,如果一样,则不存,如果不一样,则存入数据
- 当数组存满到16*0.75 = 12时,就自动扩容,每次扩容原先的2倍
HashSet元素去重复的底层原理
案例:Set集合去重复
需求
创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合,
要求:学生对象的成员变量值相同,我们就认为是同一个对象
public class Student {
private String name;
private int age;
private String sex;
public Student() {
}
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName()