您的位置:首页 > 编程语言 > Java开发

Java中equals()和hashCode()的区别与联系

2014-03-21 12:22 627 查看


Java的超类java.lang.Object定义了两个非常重要的方法:

public boolean equals(Object obj)
public int hashCode()
理解这两方法之间的区别联系是非常重要的,特别是当用户自定义的对象被添加到Map中。然而,即使高级开发人员有时无法弄清楚他们应该如何正确使用。在这篇文章中,我会先给大家看一个常见的错误的例子,然后解释如何的equals()和hashCode()之间的区别联系。

1.一个常见的​​错误

请看下面的例子:

import java.util.HashMap;

public class Apple {
private String color;

public Apple(String color) {
this.color = color;
}

public boolean equals(Object obj) {
if (!(obj instanceof Apple))
return false;
if (obj == this)
return true;
return this.color.equals(((Apple) obj).color);
}

public static void main(String[] args) {
Apple a1 = new Apple("green");
Apple a2 = new Apple("red");

//hashMap stores apple type and its quantity
HashMap<Apple, Integer> m = new HashMap<Apple, Integer>();
m.put(a1, 10);
m.put(a2, 20);
System.out.println(m.get(new Apple("green")));
}
}


在这个例子中,一个color属性为“green”的Apple对象被成功地存储在一个HashMap中,但是当Map被要求获取该对象时,结果发现Apple对象没有找到。上面的程序在控制台打印为null。但是,我们可以肯定的是,通过在调试器可以查看到对象确实是存储在HashMap中:



2.hashCode()造成的问题

这个问题是由未重写的方法hashCode()引起的。equals()和hasCode()之间的制约关系是:

1.如果两个对象是相等的,那么它们必须有相同的哈希码。

2.如果两个对象具有相同的哈希码,他们可能相等,可能不相等。

一个Map背后的想法是能够比线性搜索更快地定位到对象。使用散列键定位对象是一个两步的过程。Map内部存储对象是以数组的数组来存储。1.第一个数组的索引是hashCode()值的key。2.定位第二个数组(使用线性搜索找到的)是通过使用equal()来决定对象是否被找到?

hashCode()的默认实现是Object类为不同的对象返回不同的整数。因此,在上面的例子中,不同的对象(即使是相同类型的)具有不同的哈希码。

哈希码的存储就像车库中的序列一样,不同的车(对象)可以被存储在不同的车库中。如果你将不同的车(对象)放在不同的车库中而不是相同的车库中,那么会更有效。所以平均分配的hashCode值是一个很好的做法。(虽然不是这里的要点)

下面的例子是为一个类添加hashCode()方法的简单的解决方案,在这里,我只是用color字符串的长度作示范。

public int hashCode(){
return this.color.length();
}

相关文章:

Java
hashCode() and equals() Contract for the contains(Object o) Method of Set
HashMap
vs. TreeMap vs. Hashtable vs. LinkedHashMap
Yet
Another “Java Passes By Reference or By Value”?
What
does a Java array look like in memory?

原文:


Java equals() and hashCode() Contract

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: