文章目录
- HashSet类
- 内部存储机制
- 实验
- 1.不重写hashcode equals方法
- 2.重写,但改写equals
- 3.重写
- 参考:
HashSet类
HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。底层数据结构是哈希表
。
哈希表
一个元素为链表的数组,综合了数组与链表的优点。
HashSet具有以下特点
:
- 不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也可能发生变化;
- HashSet不是同步的;
- 集合元素值可以是null;
内部存储机制
先说结论:
HashSet在存一个新的对象的时候,先比较其跟已有的对象中的hashCode是否有相同的,如果没有相同的,则直接添加,不会调用equals方法进行判断,所以导致即使我们重写了equals方法也无法避免重复值的插入,只有当有两个hashCode相同的时候,它才会调用equals方法进行比较,如果返回的是true,则不添加,如果返回false,则添加进集合。
实验
- student.class
import java.util.Objects;public class Student {private String name;private int age;public Student(){}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
- test.class
import java.util.HashSet;public class Test {public static void main(String[] args) {Student s1 = new Student("小龙女", 23);Student s2 = new Student("任盈盈", 24);Student s3 = new Student("小龙女", 23);Student s4 = new Student("东方不败", 25);Student s5 = new Student("伊琳", 29);Student s6 = new Student("周芷若", 30);// System.out.println("s1.hashCode() = " + s1.hashCode());
// System.out.println("s3.hashCode() = " + s3.hashCode());HashSet<Student> hashSet = new HashSet<>();hashSet.add(s1);hashSet.add(s2);hashSet.add(s3);hashSet.add(s4);hashSet.add(s5);hashSet.add(s6);// "aaaa".equals()for (Student student : hashSet) {System.out.println(student.getName() + "==" + student.getAge());}}
}
1.不重写hashcode equals方法
s1.hashCode() = 1599771323
s3.hashCode() = 1876631416
小龙女==23
东方不败==25
任盈盈==24
小龙女==23
伊琳==29
周芷若==30
此时,hashset里面的内容是重复的
2.重写,但改写equals
@Overridepublic 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);return false;}@Overridepublic int hashCode() {System.out.println("Objects.hash(name,age) = " + Objects.hash(name, age));return Objects.hash(name, age);}
此时 即使hashcode的值相同,但是依然可以写入。因为当hashcode值相同时,会调用equals方法判断,name,age是否相同,此时equals返回的是false,所以依然可以添加进去
3.重写
@Overridepublic 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);}@Overridepublic int hashCode() {System.out.println("Objects.hash(name,age) = " + Objects.hash(name, age));return Objects.hash(name, age);}
此时,才是正确的结果
说下idea 重写方法的快捷键(Alt + Ins)
参考:
原文链接:https://blog.csdn.net/u012331758/article/details/45243633
原文链接:https://blog.csdn.net/mashaokang1314/article/details/83721792