想要明白hashcode作用,首先要明白java中的集合
总的来说,java集合有两类,set和list
list有序,可以重复 set无序,不可以重复
保证元素不重复需要通过什么来判断呢?
object.equals方法,如果每次增减都检查一遍效率很低
初学者可以这样理解,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。
这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。
如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,
就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。
所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
所以java中对于equals和hashcode的对比方法是这样的:
如果两个对象相同,那么hashcode一定相同;
如果两个对象hashcode相同,那么他们不一定相同;
(相同的意思是调用equals方法对比)
避免相同时候hashcode不一样,所以需要一起重写。
根据官方文档定义,抽象出这几个点
1、hashcode的存在主要是用于查找的快捷性,如hashtable,hashmap,hashcode是用在散列存储结构中确定对象的存储地址的。
2、如果两个对象相同,就是适用于equals方法,那么两个对象的hashcode一定要相同。
3、如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点;
4、两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们“存放在同一个篮子里”。
再归纳一下就是hashCode是用于查找使用的,而equals是用于比较两个对象的是否相等的。
为什么两个对象有相同的hashcode值,它们也不一定是相等的?
在这里解释一位小伙伴的问题。以下内容摘自《Head Fisrt Java》。
因为hashCode() 所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。越糟糕的杂凑算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的 hashCode)。
我们刚刚也提到了 HashSet,如果 HashSet 在对比的时候,同样的 hashcode 有多个对象,它会使用 equals() 来判断是否真的相同。也就是说 hashcode 只是用来缩小查找成本。