equal()反映的是对象或变量具体的值,即两个对象里面包含的值–可能是对象的引用,也可能是值类型的值。
而hashCode()是对象或变量通过哈希算法计算出的哈希值。
之所以有hashCode()方法,是因为在批量的对象比较中,hashCode要比equals来的快,很多集合都用到了hashCode,比如HashTable。
两个obj,如果equals()相等,hashCode()一定相等。
两个obj,如果hashCode()相等,equals()不一定相等(Hash散列值由冲突的情况,虽然概率很低)。
所以: 可以考虑在集合中,判断两个对象是否相等的规则是:
第一步: 如果hashCode()相等,则查看第二步,否则不相等。
第二步: 查看equals()是否相等,如果相等,则两obj相等,否则还是不相等。
1、equals()和hashCode()这两个方法都是从Object类中继承过来的
equals()是对两个对象的地址值进行的比较(即比较引用是否相同)。
hashCode()是一个本地方法。它的实现是根据本地机器相关的。
2、Java语言对equals()的要求如下,这些要求是必须遵循的:
A) 对称性: 如果x.equals(y)返回是”true”,那么y.equals(x)也应该返回是”true”。
B) 反射性: x.equals(x)必须返回是”true”。
C) 类推性: 如果x.equals(y)返回是”true”,而且y.equals(z)返回是”true”,那么z.equals(x)也应该返回是”true”。
D) 一致性: 如果x.equals(y)返回是”true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是”true”。
任何情况下,x.euqals(null),永远返回是”false”;x.equals(和x不同类型的对象)永远返回是”false”。
3、equals()和hashCode()
equals()相等的两个对象,hashCode()一定相等;反过来: hashCode()不等,一定能推出equals()也不等;hashCode()相等,equals()可能相等,也可能不等。
1、为什么要重载equal方法?
因为Object的equal方法默认是两个对象的引用的比较,意思就是指向同一内存,地址则相等;如果你现在需要利用对象里面的值来判断是否相等,则重载equal方法。
2、为什么重置hashCode方法?
一般的地方不需要重置hashCode,只有当类需要放在HashTable、HashMap、HashSet等等hash结构的集合时才会重载hashCode,那么为什么要重载hashCode呢?就HashMap来说,好比HashMap就是一个大内存块,里面有很多小内存块,小内存块里面是一系列的对象,可以利用hashCode来查找小内存块hashCode%size(小内存块数量),所以当equal相等时,hashCode必须相等,而且如果是Object对象,必须重载hashCode和equal方法。
3、为什么equal()相等,hashCode就一定要相等,而hashCode相等,却不要求equals相等?
1、因为是按照hashCode来访问小内存块,所以hashCode必须相等。
2、HashMap获取一个对象是比较key的hashCode相等和equal为true。之所以hashCode相等,却可以equal不等,就比如ObjectA和ObjectB他们都有属性name,那么hashCode都以name计算,所以hashCode一样,但是两个对象属于不同类型,所以equal为false。
4、为什么需要HashCode?
1、 通过hashCode可以很快的查到小内存块。
2、通过hashCode比较比equal方法快,当get时先比较hashCode,如果hashCode不同,直接返回false。
5、hashCode()作用
hashCode()方法使用来提高Map里面的搜索效率的,Map会根据不同的hashCode()来放在不同的桶里面,Map在搜索一个对象的时候先通过hashCode()找到相应的桶,然后再根据equals()方法找到相应的对象。
6、Java中的集合(Collection)有两类,一类是List,再有一类是Set。你知道它们的区别吗?前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。
那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?这就是Object.equals方法了。
但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。
也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。
哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。我们可以认为hashCode方法返回的就是对象存储的物理地址(实际可能并不是,例如:通过获取对象的物理地址然后除以8再求余,余数几是计算得到的散列值,我们就认为返回一个不是物理地址的数值,而是一个可以映射到物理地址的值)。
这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。