详解Java的hashCode()方法:返回对象的哈希码值

  • Post category:Java

当我们需要将对象放入散列表(例如HashMap)中时,我们需要实现hashCode()方法。hashCode()方法返回对象的哈希码(整数),以便在散列表中定位该对象。在此过程中,我们需要确保:

  1. 如果两个对象相等,它们的哈希码也必须相等。
  2. 如果两个对象的哈希码相等,它们不一定相等。

下面是hashCode()方法的完整攻略:

hashCode()方法的语法

public int hashCode() {
  // 计算哈希码
}

计算hashCode()值的一般步骤

  1. 将某个非0常数值,比如17,赋值给一个整型变量result。
    这个数字称作质因子。

  2. 对于对象中每个重要的域,按照以下步骤计算出一个 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 中。

  3. 最后,将 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相乘并加到结果变量中。