Java中探索的equals()和hashCode()方法_动力节点Java学院整理

  

<强> 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()方法和“==本澜峁欢问奔?当时我们知道弦对象中=方法是判断值的,而==是地址判断。

Java中探索的equals()和hashCode()方法_动力节点Java学院整理