如何重写hashCode()和equals()方法
hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它为我们的编程提供便利的同时也带来了很多危险.这篇文章我们就讨论一下如何正解理解和使用这2个方法.
如何重写equals()方法
- It is reflexive: for any non-null reference value
x,x.equals(x)should returntrue. - It is symmetric: for any non-null reference values
xandy,x.equals(y)should returntrueif and only ify.equals(x)returnstrue. - It is transitive: for any non-null reference values
x,y, andz, ifx.equals(y)returnstrueandy.equals(z)returnstrue, thenx.equals(z)should returntrue. - It is consistent: for any non-null reference values
xandy, multiple invocations ofx.equals(y)consistently returntrueor consistently returnfalse, provided no information used inequalscomparisons on the objects is modified. - For any non-null reference value
x,x.equals(null)should returnfalse.
这段话用了很多离散数学中的术数.简单说明一下:
class Coder {
private String name;
private int age;
// getters and setters
}
我们想要的是,如果2个程序员对象的name和age都是相同的,那么我们就认为这两个程序员是一个人.这时候我们就要重写其equals()方法.因为默认的equals()实际是判断两个引用是否指向内存中的同一个对象,相当于 == . 重写时要遵循以下三步:
if(other == this)
return true;
if(!(other instanceof Coder))
return false;
Coder o = (Coder)other;
return o.name.equals(name) && o.age == age;
看到这有人可能会问,第3步中有一个强制转换,如果有人将一个Integer类的对象传到了这个equals中,那么会不会扔ClassCastException呢?这个担心其实是多余的.因为我们在第二步中已经进行了instanceof 的判断,如果other是非Coder对象,甚至other是个null, 那么在这一步中都会直接返回false, 从而后面的代码得不到执行的机会.
如何重写hashCode()方法
hashCode method whenever this method(equals) is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes."@Override
public int hashCode() {
int result = 17;
result = result * 31 + name.hashCode();
result = result * 31 + age; return result;
}
String object is computed as
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)"
重写equals()而不重写hashCode()的风险
Coder c1 = new Coder("bruce", 10);
Coder c2 = new Coder("bruce", 10);
1 @Override
2 public boolean equals(Object other) {
3 System.out.println("equals method invoked!");
4
5 if(other == this)
6 return true;
7 if(!(other instanceof Coder))
8 return false;
9
10 Coder o = (Coder)other;
11 return o.name.equals(name) && o.age == age;
12 }
Set<Coder> set = new HashSet<Coder>();
set.add(c1);
再执行:
System.out.println(set.contains(c2));
我们期望contains(c2)方法返回true, 但实际上它返回了false.
我让hashCode()每次都返回一个固定的数行吗
@Override
public int hashCode() {
return 10; }
如何重写hashCode()和equals()方法的更多相关文章
- 为什么要重写hashcode和equals方法?初级程序员在面试中很少能说清楚。
我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...
- (转)为什么要重写 hashcode 和 equals 方法?
作者丨hsm_computer cnblogs.com/JavaArchitect/p/10474448.html 我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候 ...
- HashMap中使用自定义类作为Key时,为何要重写HashCode和Equals方法
之前一直不是很理解为什么要重写HashCode和Equals方法,才只能作为键值存储在HashMap中.通过下文,可以一探究竟. 首先,如果我们直接用以下的Person类作为键,存入HashMap中, ...
- 为什么要重写hashcode和equals方法
我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...
- 重写hashcode和equals方法
重写hashcode和equals方法 简乐君 2019-05-07 21:55:43 35481 收藏 191分类专栏: Java 文章标签: equals() hashcode()版权 一.前言我 ...
- 【转】 如何重写hashCode()和equals()方法
转自:http://blog.csdn.net/neosmith/article/details/17068365 hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它 ...
- Java 重写 hashCode() 和 equals() 方法
1. hashCode 1.1 基本概念 hashCode 是 JDK 根据对象的地址算出来的一个 int 数字(对象的哈希码值),代表了该对象再内存中的存储位置. hashCode() 方法是超级类 ...
- 【java编程】重写HashCode和equals方法
[一]重写equals方案的规则 equals方法本来的原则 1.类的每个实例本质上都是唯一的. 2.不关心类是否提供了“逻辑相等”的测试功能 3.超类已经覆盖了equals,从超类继承过来的行为对于 ...
- Hibernate中用到联合主键的使用方法,为何要序列化,为何要重写hashcode 和 equals 方法
联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为 ...
随机推荐
- SpringBoot 添加fastjson
1.先在项目中添加fastjson依赖: <dependency> <groupId>com.alibaba</groupId> <artifactId> ...
- 2.5 SeleniumBuilder辅助定位元素
前言对于用火狐浏览器的小伙伴们,你还在为定位元素而烦恼嘛?上古神器Selenium Builder来啦,哪里不会点哪里,妈妈再也不用担心我的定位元素问题啦!(但是也不是万能,基本上都能覆盖到) 2.5 ...
- BF字符串匹配算法
Brute Force算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符: 若不相等,则比较S的第二个 ...
- 机器学习:Kullback-Leibler Divergence (KL 散度)
今天,我们介绍机器学习里非常常用的一个概念,KL 散度,这是一个用来衡量两个概率分布的相似性的一个度量指标.我们知道,现实世界里的任何观察都可以看成表示成信息和数据,一般来说,我们无法获取数据的总体, ...
- [LeetCode&Python] Problem 896. Monotonic Array
An array is monotonic if it is either monotone increasing or monotone decreasing. An array A is mono ...
- 优先队列(挑程)poj 2431
每次写poj的题都很崩溃,貌似从来没有一次一发就ac的,每次都有特别多的细节需要考虑.还有就是自己写的太粗糙了,应该把每种情况都想到的,总是急着交,然后刷一页wa. 优先队列直接用stl就可以,简单实 ...
- 单调栈的运用-bzoj1012(代码转载-http://hzwer.com/1130.html)
Description 现在请求你维护一个数列,要求提供以下两种操作: . 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. . 插 ...
- currentStyle&getComputedStyle获取属性
方法如下: function getStyle(obj,attr){ if(obj.currentStyle){ return obj.currentStyle[attr]; // IE 中的方法 } ...
- python 闭包和迭代器
一 函数名的运用:(函数名是一个变量,但它是一个特殊变量,与括号配合可以执行变量. (1) 函数名可以赋值给其他变量 def chi(): print("吃月饼") fn=chi ...
- PTA——猴子吃桃
PTA 7-35 猴子吃桃问题 #include<stdio.h> int main() { ; scanf("%d",&n); ; i<n; i++) ...