第九条:覆盖equals时总是覆盖hashCode
(注意本文不适合学习,纯属个人笔记)
1.hashCode的作用简介
hashCode是用来提高对象的查询效率的,比如hashMap,hashMap中的键值对,我们可以通过键来查询对应的值,这个时候,键提供一个hash值就可以实现快速检索。
更深层次的内容可以看这篇文章。
2.为什么覆盖equals的时候要覆盖hashCode方法?
如果不覆盖hashCode方法,我们在需要用到hashCode的地方可能不会如我们所愿,下面看个栗子,有这么一个类,我们只覆盖了equals方法,没有覆盖hashCode方法:
public class MyObject{
private String field01;
public MyObject(String field01) {
this.field01 = field01;
}
//覆盖equals方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyObject myObject = (MyObject) o;
return (filed01 == null ? myObject.field01 == null : field01.equals(myObject.filed01));
}
}
接下来我们编写测试代码:
@Test
public void hashCode_test() throws Exception {
Map<MyObject, String> map = new HashMap<>();
map.put(new MyObject("123"), "123");
assertEquals("123", map.get(new MyObject("123")));
}
测试代码很简单,不过多介绍,现在的问题是测试能否通过?运行一下看看:
啊偶~没有通过,通过
new MyObject("123")
这个key查出的value是null。为了进一步验证我们上面的说法,我们在MyObject中继续覆盖hashCode方法:
@Override
public int hashCode() {
return filed01 != null ? filed01.hashCode() : 0;
}
行,现在在运行一次测试方法:
OK测试通过。
这个实验结果告诉我们,覆盖equals方法的时候一定要覆盖hashCode方法。
3. 如何覆盖hashCode方法?
对于大多数IDE来说都会智能实现hashCode和equals。我们可以用IDE来直接实现。