0
点赞
收藏
分享

微信扫一扫

覆盖equals时总要覆盖hashCode


在每一个覆盖了equals方法的类中,也必须覆盖hashcode方法。如果不这么做的话,就会违反Object.hashcode的通过约定,

从而导致该类无法结合所有基于散列的集合一起正常运作,这样的集合包括HashMap,HashSet和HashTable.

Object默认的hashCode是按地址所在的位置返回数据的,所以只要不是同一个对象,就会产生不同的结果,刚好和本身的equals方法吻合。

我们先做个测试,看看有什么问题:

public class PhoneNumber {
private final short areaCode;
private final short prefix;
private final short lineNumber;
public PhoneNumber(int areaCode,int prefix,int lineNumber){
rangeCheck(areaCode,999,"area code");
rangeCheck(prefix,999,"prefix");
rangeCheck(lineNumber,9999,"line number");
this.areaCode=(short)areaCode;
this.prefix=(short)prefix;
this.lineNumber=(short)lineNumber;
}
private static void rangeCheck(int arg,int max,String name){
if(arg<0||arg>max){
throw new IllegalArgumentException(name+":" +arg);
}
}
@Override
public boolean equals(Object o){
if(o==this)
return true;
if(!(o instanceof PhoneNumber))
return false;
PhoneNumber pn=(PhoneNumber)o;
return pn.getLineNumber()==lineNumber&&pn.getPrefix()==prefix&&pn.getAreaCode()==areaCode;
}

public short getPrefix() {
return prefix;
}

public short getLineNumber() {

return lineNumber;
}

public short getAreaCode() {

return areaCode;
}
public String toString(){
return "["+areaCode+","+prefix+","+lineNumber+"]";
}
}

测试:

public class Test {
public static void main(String[] args){
Map<PhoneNumber,String> m=new HashMap<>();
m.put(new PhoneNumber(707,867,5309),"Jenny");
System.out.println(m.get(new PhoneNumber(707,867,5309)));
}
}

我们理想的结果是返回Jenny,但是并不会,了解散列表的人就知道,散列表是依据散列码来存值的,不过散列码不相同,

就存在不同的桶中,当然就找不到了,所以,我们可以复写hashCode,来把我们认为相等的值返回相同的散列值,这样就

可以在hash表中找到我们想要的值。

private volatile int hashcode;
@Override
public int hashCode() {
int result=hashcode;
if(result==0){
result=17;
result=31*result+areaCode;
result=31*result+prefix;
result=31*result+lineNumber;
hashcode=result;
}
return hashcode;
}

再次测试:

Jenny

举报

相关推荐

0 条评论