HashSet 是一个无序、不可重复的集合,代码如下:
public class HashSetDemo {
public static void main(String[] args) {
Set<Student> sets = new HashSet<>();
sets.add(new Student(1,"张三",23));
sets.add(new Student(2,"李四",24));
sets.add(new Student(3,"王五",22));
sets.add(new Student(4,"赵六",27));
sets.add(new Student(4,"赵六",27));
for (Student student: sets) {
System.out.println(student);
}
}
}
运行打印结果如下:
Student{id=4, name=‘赵六‘, age=27, clazz=‘null‘, score=0.0}
Student{id=3, name=‘王五‘, age=22, clazz=‘null‘, score=0.0}
Student{id=4, name=‘赵六‘, age=27, clazz=‘null‘, score=0.0}
Student{id=1, name=‘张三‘, age=23, clazz=‘null‘, score=0.0}
Student{id=2, name=‘李四‘, age=24, clazz=‘null‘, score=0.0}
是不是结果和我们想象的不一样,HashSet 集合元素不是不重复,为何这里却发生的重复现象呀?这其实是因为 equals、hashCode 使用不规范导致的。那么,equals 和 hashCode 到底有何关系呢?为何影响 HashSet 的使用?
它们都是 Object 类中的方法,如下:
public boolean equals(Object obj)
public int hashCode()
阅读 hashCode 方法的注释如下:
通过第 1 点其实可以看出,hashCode() 在散列表中才有用,在其它情况下没用。在散列表中 hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置,当对象不会用来创建像 hashMap、hashSet 等散列表时,hashCode() 实际上用不上。
分析原因前需要了解哈希表的底层实现,hashCode 在哈希表中充当的作用:
其实在 HashSet 就是采用的这种存储和获取方式,通过 HashCode 和 equals 组合的方式来保证集合无重复。也说明了 HashCode() 在散列表中是发挥作用的
从 JDK 源码的注释中可以看出,hashCode() 在散列表中才会发挥作用,当对象无需创建像 HashMap、HashSet 等集合时,可以不用重写 hashCode() 方法,但是如果有使用到对象的哈希集合等操作时,必须重写 hashCode() 和 equals()。
Java 中 equals() 和 hashcode() 方法详解
原文:https://www.cnblogs.com/binbingg/p/14450595.html