在设计一个类的时候,很可能需要重写类的hashCode()方法,此外,在集合HashSet的使用上,我们也需要重写hashCode方法来判断集合元素是否相等。
下面给出重写hashCode()方法的基本规则:
· 在程序运行过程中,同一个对象多次调用hashCode()方法应该返回相同的值。
· 当两个对象通过equals()方法比较返回true时,则两个对象的hashCode()方法返回相等的值。
· 对象用作equals()方法比较标准的Field,都应该用来计算hashCode值。
下面给出hashCode()方法的一般规则:
1) 把对象内每个有意义的Field计算出一个int类型的hashCode值:
Boolean | hashCode=(f?0:1) |
整数类型(byte short int char) | hashCode=(int)f |
long | hashCode=(int)(f^(f>>>32)) |
float | hashCode=Float.floatToIntBits(f) |
double | long l = Double.doubleToLongBits(f); hashCode=(int)(l^(l>>>32)) |
普通引用类型 | hashCode=f.hashCode() |
2) 用第一步计算出来的多个hashCode值组合计算出一个hashCode值返回:
return f1.hashCode()+(int)f2;为了避免直接相加产生偶然相等,可以通过为各个Field乘以任意一个质数后再相加。
return f1.hashCode()*17+(int)f2*13;
示例: 向HashSet集合中添加数据:
class R { int count; public R(int count) { this.count = count; } public String toString() { return "R[count:" + count + "]"; } public boolean equals(Object obj) { if(this == obj) return true; if (obj != null && obj.getClass() == R.class) { R r = (R)obj; if (r.count == this.count) { return true; } } return false; } public int hashCode() { return this.count; } } public class HashSetTest2 { public static void main(String[] args) { HashSet hs = new HashSet(); hs.add(new R(5)); hs.add(new R(-3)); hs.add(new R(9)); hs.add(new R(-2)); //打印HashSet集合,集合元素没有重复 System.out.println(hs); //取出第一个元素 Iterator it = hs.iterator(); R first = (R)it.next(); //为第一个元素的count实例变量赋值 first.count = -3; //① //再次输出HashSet集合,集合元素有重复元素 System.out.println(hs); //删除count为-3的R对象 hs.remove(new R(-3)); // //可以看到被删除了一个R元素 System.out.println(hs); //输出false System.out.println("hs是否包含count为-3的R对象?" + hs.contains(new R(-3))); //输出false System.out.println("hs是否包含count为5的R对象?" + hs.contains(new R(5))); } }
通过以上方式,我们可以轻松的去重写一个类的hashCode()方法。