equals方法是用来干嘛的?
以下是官方说法(来自 JDK API1.7)
<span style="font-size:18px;">Indicates whether some other object is "equal to" this one. </span>
翻译:显示一些其他对象是否“等于”这一个。
hashcode方法是用来干嘛的?
以下是官方说法(来自 JDK API1.7)
<span style="font-size:18px;">Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap. </span>
翻译:返回这个对象的hash code值。这种方法支持哈希表的好处比如由java.util.HashMap提供(就是便于查找的意思)。
看equals源码
1.在没有重写equals的时候,我们调用对象的equals方法时,都是用的Object类的,
是直接比较内存地址是否一致。没有用到hashcode。源码如下:
<span style="font-size:18px;"><span style="font-size:18px;">public boolean equals(Object obj) {
return (this == obj);
}</span></span>
2.重写了equals的方法,以Integer的equals为例,
是直接比较对象内的值是否相等。没有用到hashcode。源码如下:
<span style="font-size:18px;"> public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}</span>
参考源码可得,equals方法跟HashCode方法没有直接关系。
什么时候需要重写hashcode?
AbstractSet类的hashcode方法实现的注释有这么一段
...This ensures that s1.equals(s2) implies that s1.hashCode()==s2.hashCode() for any two sets s1 and s2...
也就是说,AbstractSet这个类的equals方法相等时要求hashcode也相等的。
所以,你只要用了AbstractSet的子类,如HashSet,EntrySet等
它们判断是否为同一个对象的条件是equals()为true,并且hashcode相等。
以下是从网上弄来的一个例子:
只有同时重写hashcode和equals方法时,Set的里面才只有一个对象。
public class HashTest {
private int i;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public int hashCode() {
return i % 10;
}
public boolean equals(Object object) {
if (object == null) {
return false;
}
if (object == this) {
return true;
}
if (!(object instanceof HashTest)) {
return false;
}
HashTest other = (HashTest) object;
if (other.getI() == this.getI()) {
return true;
}
return false;
}
public final static void main(String[] args) {
HashTest a = new HashTest();
HashTest b = new HashTest();
a.setI(1);
b.setI(1);
Set<HashTest> set = new HashSet<HashTest>();
set.add(a);
set.add(b);
System.out.println(a.hashCode() == b.hashCode());
System.out.println(a.equals(b));
System.out.println(set);
}
}