hashcode的作用就是为了快速查找集合中是否存在重复元素。它是配合euqals方法使用的。
先简要介绍equals方法:在object中此方法比较两个对象的地址是不是相等。api中的一些类重写了此方法,如String重写了此方法(但StringBuffer没有重写此方法),比较的是两个字符串的内容是不是相等。因此我们在定义一个对象的时候也可以重写equals方法,按照我们的原则来定义。
再看一个问题:
为什么重写了equals方法需要重写hashcode方法?
答:为了更快判断集合中是否已存在某对象。对于链表和数组,如果我们要查找某个元素是否已经存在,我们需要遍历数组和链表,直到找到这个元素位置,这样很耗时间(事实上,链表和数组在加入一个元素时也没有判断它是否存在,因此可以有重复)。如果我们使用哈希表,我们就可以根据这个元素的hashcode方法和equals方法快速判断集合中是否已存在某对象。下面对此进行描述:
哈希表由哈希表元地址和哈希表元组成,是一个链表的数组。在java中,哈希码就是根据对象的hashcode方法产生的哈希码(hashcode一般是根据对象的成员变量生成哈希码)。一般而言,不同的对象有不同的hashcode,但也可能不同的对象拥有同一个哈希码。但是哈希表元地址是如何与哈希码匹配的呢?举个例子吧:
假设现在有16个哈希表元,那么哈希表元地址则为1到16,然后现在有个对象的哈希码为329,329%16=9,则这个对象就存储在哈希表元地址为9的哈希表元上。假设现在又有一个对象的哈希码为25,25%16=9,好的,由于哈希地址为9的哈希表元上已经有元素了,这时新存进来的对象就要遍历这个哈希表元(不是全部元素),通过equals方法判断这个哈希表元上是否已经存在相同对象,如果不存在,就继续存储在哈希表元的后面。
总结如下:每要添加一个对象,都是先获取它的hashcode值,然后一次就匹配了哈希表元地址,如果哈希表元上还没有存储对象,就直接存储,如果已经有了就遍历哈希表元(通过equals方法判断是否有相同对象存在),如果不存在相同对象就存储在哈希表元后面。
现在我们来看看HashSet的add方法,当add一个对象时,会根据这个对象生成的hashcode值快速到链表数组中匹配对应的哈希表元,如果哈希表元为空的,就可以把对象插入哈希表元中,然后返回true。如果哈希表元中已经有元素,这时就要遍历这个哈希表元(记住,只是遍历其中一个哈希表元,而不是集合中的所有元素,可能就一两个元素),通过equals方法来判断是否已经有相同的对象存在,如果有则返回false,如果没有则找空间存贮对象并链接到这个哈希表元的后面。
看完这里应该就明白了为什么重写equals方法还要重写hashcode方法,就是为了快速查找集合中是否存在重复元素。
记住一个原则:如果a.equals(b)为true时,a和b必须拥有相同的hashcode。
举个例子说明:
- public class Person {
-
private String name;
-
private int age;
-
-
@Override
-
public int hashCode() {
-
return age+name.hashCode();
- }
-
@Override
-
public boolean equals(Object obj) {
-
if (this == obj)
-
return true;
-
if (obj == null)
-
return false;
-
if (getClass() != obj.getClass())
-
return false;
- Test3 other = (Test3) obj;
-
if (age != other.age)
-
return false;
-
if (name == null) {
-
if (other.name != null)
-
return false;
-
} else if (!name.equals(other.name))
-
return false;
-
return true;
- }
- }
- Person p1 = new Person();
-
Person p2 = new Person();
我们上述实现的equals方法和hashcode方法必须满足下面条件:
1. p1.equals(p2)为true时,p1和p2必须拥有相同的哈希码。
2. p1和p2拥有相同的哈希码时,p1.equals(p2)不一定为true。
对于第二点我们可以设想一下:
- p1.age=24; p1.name.hashcode=109;
-
p2.age=27;p2.name.hashcode=106;
因此p1和p2的hashcode相同,但p1.equals(p2)为false。
分享到:
相关推荐
主要介绍了详解hashCode()和equals()的本质区别和联系,本文先对两种方法作了介绍,然后对二者联系进行分析,具有一定参考价值,需要的朋友可以了解下。
hashcode是用来查找的,如果你学过数据结构就应该知道,在查找和排序这一章有……
NULL 博文链接:https://songjianyong.iteye.com/blog/1676894
java中hashcode和equals的详解.pdf
更清楚的了解hashcode()和equals()方法。
有许多人学了很长时间的Java,但一直不明白hashCode方法的作用以及equals()和==的区别,我来解释一下吧。首先,想要明白hashCode的作用,你必须要先知道Java中的集合。总的来说,Java中的集合(Collection)有两类,...
但是为什么JavaDoc明确的告诉我们, hashCode()和equals()要一起重写呢?原因是因为,在Java自带的容器HashMap和HashSet中, 都需同时要用到对象的hashCode()和equals()方法来进行判断,然后再插入删除元素,这点...
java中hashcode()和equals()的详解.docx
如果一个类的hashCode()方法没有遵循上述要求,那么,当这个类的两个实例对象用equals()方法比较的结果相等时,他们本来应该无法被同时存储进set集合
本文档详细介绍了set接口为什么会用到hashCode和equals方法以及这两个方法的一些探讨 set不同的实现类用到的这两个方法也不同
主要介绍了详解Java中hashCode的作用的相关资料,需要的朋友可以参考下
1.概述 2.为什么重写equels方法要重写hashcode方法 3.例子
本文详细解释了JAVA hashCode的使用方法,提供了测试hashCode和equals方法的使用实例
Java中入HashMap等一些键值对应的结构,基本上都可以用hashCode()来查找值,接下来我们就来详解Java中用于查找对象哈希码值的hashCode()函数:
主要给大家介绍了关于java中为什么重写equals时必须重写hashCode方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
下面小编就为大家带来一篇java中重写equals()方法的同时要重写hashcode()方法(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
本篇文章详细介绍了Java中的equals和hashCode方法详解,Object 类是所有类的父类,非常具有实用价值,需要的朋友可以参考下。
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `pic` varchar(50) NOT NULL, `hashcode` varchar(16) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREME