为什么hashCode()在所有连续执行中为对象返回相同的值?

时间:2010-06-06 07:24:49

标签: java equality

我在java中尝试一些围绕对象相等的代码。正如我在某处读到的那样

  

hashCode()是通过应用散列函数生成的数字。散列函数对于每个对象可以是不同的,但也可以是相同的。在对象级别,它返回对象的内存地址。

现在,我有一个示例程序,我连续运行了10次。每次运行程序时,我都会获得与哈希码相同的值。

如果hashCode()函数返回对象的内存位置,那么java(JVM)如何在连续运行中将对象存储在相同的内存地址?

你能否就这个问题给我一些见解和看法?

我正在运行以测试此行为的程序如下:

public class EqualityIndex {

    private int index;

    public EqualityIndex(int initialIndex) {
       this.index = initialIndex;
    }

    public static void main(String[] args) {
        EqualityIndex ei = new EqualityIndex(2);
        System.out.println(ei.hashCode());
    }

}

每次运行此程序时,返回的哈希码值为4072869

8 个答案:

答案 0 :(得分:14)

  

为什么java(JVM)在连续运行中将对象存储在相同的内存地址?

为什么不呢?非内核程序永远不会使用绝对内存地址,它们使用虚拟内存,每个进程都有自己的地址空间。因此,毫无疑问,确定性程序会在每次运行中将内容放在同一位置。

答案 1 :(得分:3)

嗯,对象很可能最终位于虚拟内存中的相同位置。没有任何矛盾。最重要的是你无论如何都不应该在意。 如果实现hashCode以返回与内部存储地址相关的内容(根本无法保证!),无论如何,您无法使用该信息。

答案 2 :(得分:3)

hashCode()函数应该为同一个执行中的同一个对象返回相同的值。不必为不同的执行返回相同的值。请参阅从Object课程中提取的以下注释。

  

hashCode的一般合约是:

     

每当在同一个对象上多次调用它时   执行Java应用程序的hashCode方法   必须始终返回相同的整数,前提是没有信息   用于对象的equals比较被修改。   此整数不需要在执行一次时保持一致   应用于同一应用程序的另一次执行。

我已经执行了几次代码。 这是我的结果

1935465023

1425840452

1935465023

1935465023

1935465023

1925529038

1935465023

1935465023

相同的数字重复多次。但这并不意味着它们总是一样的。让我们假设,JVM的一个特定实现是在内存中寻找第一个空闲插槽。那么如果你没有运行任何其他应用程序,那么在同一个插槽中分配对象的可能性很高。

答案 3 :(得分:2)

您创建了哪种对象?它是一种特定的对象,如String(例如)。如果它是特定类型,则类可以覆盖hashCode()方法并将其返回给您。在这种情况下,你收到的不再是内存地址了。

以及您收到的值,您确定它是否是内存地址?

因此,请发布更多代码以获取更多详细信息

答案 4 :(得分:2)

  

正如我在某处读到的那样:“...在对象级别,它返回对象的内存地址。”

该陈述不正确,或者至多是过于简单化。

该语句指的是Object.hashCode()的默认实现,它返回与System.identityHashcode(Object)相同的值。

Object.hashCode()的Javadoc说:

  

尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言不需要此实现技术。)

和此:

  

每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象的equals比较中使用的信息。

实际上,当首次为对象调用该方法时,标识哈希码值通常基于对象的机器地址。该值存储在Object标头的隐藏字段中。这允许在后续调用中返回相同的哈希码...即使GC在此期间重新定位了对象。

请注意,如果标识哈希码值在对象的生命周期内发生了变化,则会违反hashcode()的合同,并且作为哈希码无效。

答案 5 :(得分:1)

hashCode可以并且可以被您正在使用的类覆盖,the JavaDoc for Object.hashCode()表明它是'...通常通过将对象的内部地址转换为整数来实现...'所以实际的实现可能与系统有关。另请注意JavaDoc中的第三点,即两个不相等的对象不需要返回不同的hashCodes。

答案 6 :(得分:1)

for (int i=0; i < 10; i++) {
    System.out.println("i: " + i + ", hashCode: " + new Object().hashCode());
}

打印:


i: 0, hashCode: 1476323068
i: 1, hashCode: 535746438
i: 2, hashCode: 2038935242
i: 3, hashCode: 988057115
i: 4, hashCode: 1932373201
i: 5, hashCode: 1001195626
i: 6, hashCode: 1560511937
i: 7, hashCode: 306344348
i: 8, hashCode: 1211154977
i: 9, hashCode: 2031692173

答案 7 :(得分:0)

如果两个对象相等,则它们必须具有相同的哈希码。因此,只要您不创建普通的Object实例,每次创建具有相同值的对象时,您将获得相同的哈希码。