HashSet内部的数据结构是一个哈希表,它通过键值对的方式去存储数据,底层实际上是维护了一个HashMap,因为HashMap中的key是不可重复的。
两个对象的hashcode相等的情况下,equals方法不一定相等,但是如果equals方法相等的情况下,两个对象的hashcode一定是相等的。
这里可以理解为不同对象可能会产生相同的hashcode,但是相同对象的hashcode一定是相同的。
在java的集合中,判断两个对象是否相等的规则是:
1.判断两个对象得到hashcode()是否相等
如果两个对象的hashcode()是相当的,那么就转入2,如果不相等则说明两个对象是不相等的返回false。
实际上先比较hashcode()在比较equals来判断两个对象是否相等是为了考虑执行效率。理论是不比较hashcode()也是可行的,但是在效率上会大大降低。
2.判断两个对象的equals方式是否返回true
如果equals方法返回结果是true,则代表两个两个对象相等,
如果返回值为false,则代表两个对象不相等
在这里大家可能会问,为什么要添加两个条件呢?只需要条件2不久可以达到比较两个对象是否相等了吗?
这里通过两个步骤来比较对象是否相等的原因是因为直接比较hashcode的效率比较高,能过滤出大部分不相同的对象,但是前面也有说到,hashcode相同的对象,equals方法可能是不同的,所以需要步骤2去完善返回的结果。
在HashMap中添加元素得到时候,会通过hashcode计算出元素在Map存放的位置,如果该位置为null则直接存入该位置,如果该位置不为null则比较两个对象是否相等,如果相等则覆盖,如果不等则存储(但是实际情况中不会存在不等的情况除非手动修改了重写的equals或者hashcode()方法)