<强> equals()和hashCode()区别? 强>
-
<李> & # 61548;,等于():反映的是对象或变量具体的值,即两个对象里面包含的值,可能是对象的引用,也可能是值类型的值。李>
<李> & # 61548;,hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数。根类对象的hashCode()方法的计算依赖于对象实例的D(内存地址),故每个对象对象的hashCode都是唯一的;当然,当对象所对应的类重写了hashCode()方法时,结果就截然不同了。李>
之所以有hashCode方法,是因为在批量的对象比较中、hashCode要比=来得快,很多集合都用到了hashCode,比如HashTable只
两个obj,如果=()相等,hashCode()一定相等。
两个obj,如果hashCode()相等,等于()不一定相等(哈希散列值有冲突的情况,虽然概率很低)。
所以:
可以考虑在集合中,判断两个对象是否相等的规则是:
第一步,如果hashCode()相等,则查看第二步,否则不相等;
第二步,查看=()是否相等,如果相等,则两obj相等,否则还是不相等。
1,首先equals()和hashcode()这两个方法都是从对象类中继承过来的。
equals()是对两个对象的地址值进行的比较(即比较引用是否相同)。
hashCode()是一个本地方法,它的实现是根据本地机器相关的。
2,爪哇语言对=()的要求如下,这些要求是必须遵循的:
对称性:如果x.e quals (y)返回是“真正的”,那么y.equals (x)也应该返回是“真正的”。
B反射性:x.e quals (x)必须返回是“真正的”。
C类推性:如果x.e quals (y)返回是“真正的”,而且y.equals (z)返回是“真正的”,那么z.equals (x)也应该返回是“真正的”。
D一致性:如果x.e quals (y)返回是“真正的”,只要x和y内容一直不变,不管你重复x.e quals (y)多少次,返回都是“真的”。
任何情况下,x.e quals (null),永远返回是“假”,x.e quals(和x不同类型的对象)永远返回是“错误的”。
3, equals()相等的两个对象,hashcode()一定相等;
反过来:hashcode()不等,一定能推出=()也不等;
hashcode()相等,等于()可能相等,也可能不等。
<强>为什么选择hashcode方法? 强>
以java . lang . Object来理解,JVM每新的一个对象,它都会将这个对象丢到一个散列哈希表中去,这样的话,下次做对象的比较或者取这个对象的时候,它会根据对象的hashcode再从哈希表中取这个对象。这样做的目的是提高取对象的效率。具体过程是这样:
1。新对象(),JVM根据这个对象的Hashcode值,放入到对应的哈希表对应的键上,如果不同的对象确产生了相同的哈希值,也就是发生了哈希键相同导致冲突的情况,那么就在这个哈希关键的地方产生一个链表,将所有产生相同Hashcode的对象放到这个单链表上的去,串在一起。
2。比较两个对象的时候,首先根据他们的hashcode去哈希表中找他的对象,当两个对象的hashcode相同,那么就是说他们这两个对象放在哈希表中的同一个键上,那么他们一定在这个键上的链表上。那么此时就只能根据对象的相等的方法来比较这个对象是否相等。当两个对象的hashcode不同的话,肯定他们不能平等。
下面我举个例子详细说明下。
列表是可以重复的,集是不可以重复的。那么设置存储数据的时候是怎样判断存进的数据是否已经存在。使用=()方法呢,还是hashcode()方法。
假如用equals(),那么存储一个元素就要跟已存在的所有元素比较一遍,比如已存入100个元素,那么存101个元素的时候,就要调用=方法100次。
但如果用hashcode()方法的话,他就利用了哈希算法来存储数据的。这样的话每存一个数据就调用一次hashcode()方法,得到一个hashcode值及存入的位置。如果该位置不存在数据那么就直接存入,否则调用一次=()方法,不相同则存,相同不存。这样下来整个存储下来不需要调用几次=方法,虽然多了几次hashcode方法,但相对于前面来讲效率高了不少。
<强>为什么要重写=方法? 强>
因为对象的相等的方法默认是两个对象的引用的比较,意思就是指向同一内存,地址则相等,否则不相等;如果你现在需要利用对象里面的值来判断是否相等,则重载相同的方法。
说道这个地方我相信很多人会有疑问,相信大家都被弦对象的equals()方法和“==本澜峁欢问奔?当时我们知道弦对象中=方法是判断值的,而==是地址判断。