没有合适的资源?快使用搜索试试~ 我知道了~
java中hashcode和equals的详解.pdf
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 76 浏览量
2021-11-25
10:03:22
上传
评论
收藏 40KB PDF 举报
温馨提示
试读
14页
java中hashcode和equals的详解.pdf
资源推荐
资源详情
资源评论
1
如果函数返回类型不同,子类的同名函数不能继承父类的同名函数
c++ 如果返回值类型是基本数据类型,必须相同,不然编译不通过。如果返回值类型
是类类型,可以不相同
hashcode方法浅析
有许多人学了很长时间的 Java,但一直不明白 hashCode方法的作用,我来解释
一下吧。首先,想要明白 hashCode的作用,你必须要先知道 Java 中的集合。 总
的来说, Java 中的集合( Collection )有两类,一类是 List ,再有一类是 Set。
你知道它们的区别吗? 前者集合内的元素是有序的, 元素可以重复; 后者元素无
序,但元素不可重复。 那么这里就有一个比较严重的问题了: 要想保证元素不重
复,可两个元素是否重复应该依据什么来判断呢?这就是 Object.equals 方法
了。但是,如果每增加一个元素就检查一次, 那么当元素很多时, 后添加到集合
中的元素比较的次数就非常多了。也就是说,如果集合中现在已经有 1000 个元
素,那么第 1001 个元素加入集合时,它就要调用 1000 次 equals 方法。这显然
会大大降低效率。 于是, Java 采用了哈希表的原理。哈希( Hash)实际上
是个人名, 由于他提出一哈希算法的概念, 所以就以他的名字命名了。 哈希算法
也称为散列算法, 是将数据依特定算法直接指定到一个地址上。 如果详细讲解哈
希算法,那需要更多的文章篇幅,我在这里就不介绍了。初学者可以这样理解,
hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不
是)。 这样一来,当集合要添加新的元素时,先调用这个元素的 hashCode
方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,
它就可以直接存储在这个位置上, 不用再进行任何比较了; 如果这个位置上已经
有元素了,就调用它的 equals 方法与新元素进行比较,相同的话就不存了,不
相同就散列其它的地址。 所以这里存在一个冲突解决的问题。 这样一来实际调用
equals 方法的次数就大大降低了,几乎只需要一两次。 所以, Java 对于
eqauls 方法和 hashCode方法是这样规定的: 1、如果两个对象相同,那么它们
的 hashCode值一定要相同; 2、如果两个对象的 hashCode相同,它们并不一定
相同 上面说的对象相同指的是用 eqauls 方法比较。 你当然可以不按要
求去做了, 但你会发现, 相同的对象可以出现在 Set 集合中。 同时,增加新元素
的效率会大大下降。
java 中 hashcode()和 equals()的详解
1. 首先 equals()和 hashcode()这两个方法都是从 object 类中继承过来的。
equals()方法在 object 类中定义如下:
public boolean equals(Object obj) {
return (this == obj);
}
很明显是对两个对象的地址值进行的比较(即比较引用是否相同) 。但是我们必需清楚,当
String 、Math、还有 Integer、Double。。。。等这些封装类在使用 equals()方法时,已经覆盖了
object 类的 equals()方法。比如在 String 类中如下:
2
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
很明显,这是进行的内容比较, 而已经不再是地址的比较。 依次类推 Double 、Integer、Math。。。。
等等这些类都是重写了 equals()方法的,从而进行的是内容的比较。当然了基本类型是进行
值的比较,这个没有什么好说的。
我们还应该注意, Java 语言对 equals()的要求如下,这些要求是必须遵循的:
? 对称性:如果 x.equals(y)返回是“ true”,那么 y.equals(x) 也应该返回是“ true”。
? 反射性: x.equals(x) 必须返回是“ true”。
? 类推性:如果 x.equals(y)返回是“ true”,而且 y.equals(z)返回是“ true”,那么 z.equals(x)
也应该返回是“ true”。
? 还有一致性:如果 x.equals(y) 返回是“true”,只要 x 和 y 内容一直不变, 不管你重复 x.equals(y)
多少次,返回都是“ true”。
? 任何情况下, x.equals(null) ,永远返回是“ false”;x.equals(和 x 不同类型的对象 )永远返回
是“ false”。
以上这五点是重写 equals()方法时,必须遵守的准则,如果违反会出现意想不到的结果,请
大家一定要遵守。
2. 其次是 hashcode() 方法,在 object 类中定义如下:
public native int hashCode();
说明是一个本地方法, 它的实现是根据本地机器相关的。 当然我们可以在自己写的类中覆盖
hashcode()方法,比如 String 、Integer、Double。。。。等等这些类都是覆盖了 hashcode()方法的。
例如在 String 类中定义的 hashcode()方法如下:
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
3
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
解释一下这个程序( String 的 API 中写到):
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用 int 算法,这里 s[i] 是字符串的第 i 个字符, n 是字符串的长度, ^ 表示求幂。(空
字符串的哈希码为 0。)
3.这里我们首先要明白一个问题:
equals()相等的两个对象, hashcode()一定相等;
equals()不相等的两个对象,却并不能证明他们的 hashcode()不相等。换句话说, equals()
方法不相等的两个对象, hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生
冲突造成的) 。
反过来: hashcode()不等,一定能推出 equals()也不等; hashcode()相等, equals()可能相等,
也可能不等。 解释下第 3 点的使用范围,我的理解是在 object、String 等类中都能使用。在
object 类中, hashcode()方法是本地方法,返回的是对象的地址值,而 object 类中的 equals()
方法比较的也是两个对象的地址值,如果 equals()相等,说明两个对象地址值也相等,当然
hashcode()也就相等了;在 String 类中, equals()返回的是两个对象内容的比较,当两个对象
内容相等时,
Hashcode()方法根据 String 类的重写(第 2 点里面已经分析了)代码的分析,也可知道
hashcode()返回结果也会相等。以此类推,可以知道 Integer 、Double 等封装类中经过重写的
equals()和 hashcode()方法也同样适合于这个原则。当然没有经过重写的类,在继承了 object
类的 equals()和 hashcode()方法后,也会遵守这个原则。
4.谈到 hashcode()和 equals()就不能不说到 hashset,hashmap,hashtable中的使用,具体是怎样
呢,请看如下分析:
Hashset 是继承 Set 接口, Set 接口又实现 Collection 接口,这是层次关系。那么 hashset是根
据什么原理来存取对象的呢?
在 hashset中不允许出现重复对象, 元素的位置也是不确定的。 在 hashset 中又是怎样判定元
素是否重复的呢?这就是问题的关键所在, 经过一下午的查询求证终于获得了一点启示, 和
大家分享一下,在 java 的集合中,判断两个对象是否相等的规则是:
1),判断两个对象的 hashCode 是否相等
如果不相等,认为两个对象也不相等,完毕
如果相等,转入 2)
(这一点只是为了提高存储效率而要求的, 其实理论上没有也可以, 但如果没有, 实际使用
时效率会大大降低,所以我们这里将其做为必需的。后面会重点讲到这个问题。 )
2),判断两个对象用 equals 运算是否相等
剩余13页未读,继续阅读
资源评论
songyunc
- 粉丝: 0
- 资源: 3万+
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功