在设计一个类的时候,很可能需要重写类的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()方法。