当我们需要将对象放入散列表(例如HashMap)中时,我们需要实现hashCode()方法。hashCode()方法返回对象的哈希码(整数),以便在散列表中定位该对象。在此过程中,我们需要确保:
- 如果两个对象相等,它们的哈希码也必须相等。
- 如果两个对象的哈希码相等,它们不一定相等。
下面是hashCode()方法的完整攻略:
hashCode()方法的语法
public int hashCode() {
// 计算哈希码
}
计算hashCode()值的一般步骤
-
将某个非0常数值,比如17,赋值给一个整型变量result。
这个数字称作质因子。 -
对于对象中每个重要的域,按照以下步骤计算出一个 int 值:
a) 如果域是 boolean 类型,则计算 (f ? 1 : 0)。
b) 如果域是 byte、char、short 或者 int 类型,则计算 (int) f。
c) 如果域是 long 类型,则计算 (int) (f ^ (f >>> 32))。
d) 如果域是 float 类型,则计算 Float.floatToIntBits(f)。
e) 如果域是 double 类型,则计算 Double.doubleToLongBits(f),然后按照步骤 2c 将结果转换成一个 int 类型。
f) 如果域是对象引用,并且该类的 equals 方法通过递归调用可以整体用该方法来比较,则同样调用该域的 hashCode 方法,并将结果合并到 result 中。
g) 如果域是对象引用,但该域的 equals 方法比较此类所用的标准不适用,则使用 System.identityHashCode 方法来返回该域的哈希码,然后将其合并到 result 中。 -
最后,将 result 返回。
示例1
现在我们以Person类为例,该类有两个属性name和age:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
在该类中,我们实现hashCode()方法,并遵循以上步骤来计算哈希码。
public int hashCode() {
int result = 17;
result = 31 * result + name.hashCode();
result = 31 * result + age;
return result;
}
在这个示例中,我们选择了质因子17和31。我们首先为结果变量result赋值为17,然后按步骤2计算name和age的哈希码。最后,将哈希码与31相乘并加到结果变量中。
示例2
现在我们以Point类为例,该类有两个属性x和y:
class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
在该类中,我们实现hashCode()方法,并遵循以上步骤来计算哈希码。
public int hashCode() {
int result = 17;
result = 31 * result + x;
result = 31 * result + y;
return result;
}
在这个示例中,我们选择了质因子17和31。我们首先为结果变量result赋值为17,然后按步骤2计算x和y的哈希码。最后,将哈希码与31相乘并加到结果变量中。