System.idendityHashCode()和hashCode()方法的内部工作是什么?

时间:2015-01-21 13:38:28

标签: java hashcode

我阅读了关于 System.identityHashCode(Object x)的内容。你不能覆盖它,因为它的静态方法,但我可以覆盖对象的hashCode 方法。这也是javadoc中 System.identityHashCode(Object x)的提到:

  

返回与默认方法hashCode()返回的给定对象相同的哈希码,无论给定对象的类是否覆盖        hashCode()。空引用的哈希码为零。

但是当我通过在println方法中交换对象而在代码下运行时,我得到了相同的结果。

public class SherlockGCD {
    public int hashCode()
      {
       return super.hashCode();
      }
    public static void main(String[] args) {
      SherlockGCD sher= new SherlockGCD();
      SherlockGCD sher1= new SherlockGCD();
      System.out.println(System.identityHashCode(sher));
      System.out.println(sher1.hashCode());
     }
    }

输出是:

31866429

16795905

但是如果您将对象交换如下,那么也是相同的输出

    System.out.println(System.identityHashCode(sher1));
    System.out.println(sher.hashCode());

输出是:

31866429

16795905

那么为什么输出不是反转,因为我在更改println方法中的对象?

2 个答案:

答案 0 :(得分:3)

  

但是当我通过在println方法中交换对象而在代码下运行时,我得到的结果相同。

您不应该将一次运行中hashCode的结果与不同运行中的结果进行比较。例如,你可能观察到的是懒惰地分配了身份哈希码 - 所以你请求哈希码的对象首先获得31866429而下一个获得16795905 - 在你的特定系统上。

如果您在单次运行中反转订单,您应该会看到一致的结果:

System.out.println(System.identityHashCode(sher));
System.out.println(sher1.hashCode());
System.out.println(System.identityHashCode(sher1));
System.out.println(sher.hashCode());

此处输出的第1行和第4行应具有相同的值,而第2行和第3行应具有相同的值。

答案 1 :(得分:1)

目前还不清楚你要做什么。给定的对象引用具有给定的hashCode。这将针对identityHashCode和未覆盖的hashCode返回。但是,您有两个不同的对象引用。因此,如果Object.hashCode未被覆盖,则这些将具有不同的hashCodes。

你在运行之间看到相同的hashCodes是偶然的。如果你这样做的时间足够长,并且在足够的JVM重新启动时不会出现这种情况。

您确实以相同的顺序看到相同的hashCodes这一事实是因为只有在您第一次调用hashCode时才将hashCodes分配给对象引用,而不是在创建对象时。因此,对hashCode的第一次调用获取两次运行中的第一个代码,无论它是哪个对象。

尝试

  // both lines output the same hashCode for sher
  System.out.println(System.identityHashCode(sher));
  System.out.println(sher.hashCode());

  // both lines output the same hashCode for sher1
  System.out.println(System.identityHashCode(sher1));
  System.out.println(sher1.hashCode());

如果你把所有4条线放在一起,你会看到两条相同的线,然后是两条与第一条线不同的相同线。

如果你现在想要为hashCode()identityHashCode返回一个不同的hashCode,那么添加一个字段并在你的覆盖中返回一个hashCode:

public class SherlockGCD {
  private int id;
  public SherlockGD(int id) { this.id = id; }
  public int hashCode()
  {
    return id;
  }
  ...