hash code、equals和“==”三者的关系

两个对象值相同(x.equals(y) == true),则必定有相同的hash code。java

 

这是java语言的定义: c++

由于:Hash,通常翻译作“散列”,也有直接音译为"哈希"的,就是把任意长度的输入(又叫作预映射, pre-image),经过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间一般远小于输入的空间,不一样的输入可能会散列成相同的输出,而不可能从散列值来惟一的肯定输入值。
1) 对象相等则hashCode必定相等;
2) hashCode相等对象未必相等。面试

 

== 是比较地址是否相等,JAVA中声明变量都是引用嘛,不一样的引用,可能指向同一个地址。

equals 是比较值是否相等。

这种题很容易在面试中被问到。。。算法

 

hash code、equals和“==”三者的关系翻译

 

1.若是是基本变量,没有hashcode和equals方法,基本变量的比较方式就只有==,;

2.若是是变量,因为在java中全部变量定义都是一个指向实际存储的一个句柄(你能够理解为c++中的指针),在这里==是比较句柄的地址(你能够理解为指针的存储地址),而不是句柄指向的实际内存中的内容,若是要比较实际内存中的内容,那就要用equals方法,可是!!!

若是是你本身定义的一个类,比较自定义类用equals和==是同样的,都是比较句柄地址,由于自定义的类是继承于object,而object中的equals就是用==来实现的,你能够看源码。

那为何咱们用的String等等类型equals是比较实际内容呢,是由于String等经常使用类已经重写了object中的equals方法,让equals来比较实际内容,你也能够看源码。

3. hashcode
在通常的应用中你不须要了解hashcode的用法,但当你用到hashmap,hashset等集合类时要注意下hashcode。

你想经过一个object的key来拿hashmap的value,hashmap的工做方法是,经过你传入的object的hashcode在内存中找地址,当找到这个地址后再经过equals方法来比较这个地址中的内容是否和你原来放进去的同样,同样就取出value。

因此这里要匹配2部分,hashcode和equals
但假如说你new一个object做为key去拿value是永远得不到结果的,由于每次new一个object,这个object的hashcode是永远不一样的,因此咱们要重写hashcode,你能够令你的hashcode是object中的一个恒量,这样永远能够经过你的object的hashcode来找到key的地址,而后你要重写你的equals方法,使内存中的内容也相等。。。指针

 

 

首先,从语法角度,也就是从强制性的角度来讲,hashCode和equals是两个独立的,互不隶属,互不依赖的方法,equals成立与hashCode相等这两个命题之间,谁也不是谁的充分条件或者必要条件。  
   
  可是,从为了让咱们的程序正常运行的角度,咱们应当向Effective   Java中所言  
   
  重载equals的时候,必定要(正确)重载hashCode  
   
  使得equals成立的时候,hashCode相等,也就是a.equals(b)->a.hashCode()   ==   b.hashCode(),或者说此时,equals是hashCode相等的充分条件,hashCode相等是equals的必要条件(从数学课上咱们知道它的逆否命题:hashCode不相等也不会equals),可是它的逆命题,hashCode相等必定equals以及否命题不equals时hashCode不等都不成立。  
   
  因此,若是面试的时候,最好把hashCode与equals之间没有强制关系,以及根据(没有语法约束力的)规范的角度,应当作到...这两层意思都说出来:P  code

 

 

  总结一下,equals()是对象相等性比较,hashCode()是计算对象的散列值,固然他们的依据是对象的属性。对象

 对于equals,通常咱们认为两个对象同类型而且全部属性相等的时候才是相等的,在类中必须改写equals,由于Object类中的equals只是判断两个引用变量是否引用同一对象,若是不是引用同一对象,即便两个对象的内容彻底相同,也会返回false。固然,在类中改写这个equals时,你也能够只对部分属性进行比较,只要这些属性相同就认为对象是相等的。  
   
  对于hashCode,只要是用在和哈希运算有关的地方,前面不少兄弟都提到了,和equals同样,在你的类中也应该改写。固然若是两个对象是彻底相同的,那么他们的hashCode固然也是同样的,可是象前面所述,规则能够由你本身来定义,所以二者之间并无什么必然的联系。  
   
  固然,大多数状况下咱们仍是根据全部的属性来计算hashCode和进行相等性比较。继承

相关文章
相关标签/搜索