HashSet、LinkedHashSet详解
HashSet底层原理:
采用哈希表存储数据。JDK8以前,哈希表由数组+链表组成。JDK8开始,由数组+链表+红黑树组成。
①创建一个默认长度16, 默认加载因为0.75的数组,数组名table
②根据元素的哈希值跟数组的长度计算出应存入的位置
③判断当前位置是否为null, 如果是null直接存入
④如果位置不为null, 表示有元素,则调用equals方法比较属性值
⑤一样:不存 不一样:存入数组,形成链表
JDK8以前:新元素存入数组,老元素挂在新元素下面
JDK8以后:新元素直接挂在老元素下面
注意:JDK8以后,当链表长度超过8,而且数组长度大于等于64时,自动转换为红黑树
如果集合中存储的是自定义对象,必须重写hashCode和equals方法
(利用hashCode方法得到哈希值,可以确定该元素添加到数组的哪个位置。利用equals比较对 象内部的属性值是否相同)
代码练习:
利用HashSet集合去除重复元素
需求:创建一个存储学生对象的集合,存储多个学生对象。使用程序实现在控制台遍历该集合。
要求:学生对象的成员变量值相同,我们就认为是同一个对象
public class Student {private String name;private int age;public Student(){}public Student(String name,int age) {this.name = name;this.age = age;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);} }
public class A02_HashSetDemo1 {public static void main(String[] args) {//1.创建三个学生对象Student s1 = new Student("zhangsan",23);Student s2 = new Student("lisi",24);Student s3 = new Student("wangwu",25);Student s4 = new Student("zhangsan",23);//2.创建集合用来添加学生HashSet<Student> hs = new HashSet<>();//3.添加元素System.out.println(hs.add(s1));//trueSystem.out.println(hs.add(s2));//trueSystem.out.println(hs.add(s3));//trueSystem.out.println(hs.add(s4));//false//4.打印集合System.out.println(hs);} }
LinkedHashSet底层原理
●有序、不重复、无索引。
●这里的有序指的是保证存储和取出的元素顺序一致
●原理:底层数据结构是依然哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序。
代码:
public class A03_LinkedHashSetDemo3 {public static void main(String[] args) {//1.创建四个学生对象Student s1 = new Student("zhangsan",23);Student s2 = new Student("lisi",24);Student s3 = new Student("wangwu",25);Student s4 = new Student("zhangsan",23);//2.创建集合对象LinkedHashSet<Student> lsh = new LinkedHashSet<>();System.out.println(lsh.add(s1));System.out.println(lsh.add(s2));System.out.println(lsh.add(s3));System.out.println(lsh.add(s4));//flaseSystem.out.println(lsh);} }