Java Array HashCode 实现

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/744735/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:58:38  来源:igfitidea点击:

Java Array HashCode implementation

javainthashcode

提问by souLTower

This is odd. A co-worker asked about the implementation of myArray.hashCode() in java. I thought I knew but then I ran a few tests. Check the code below. The odd think I noticed is that when I wrote the first sys out the results were different. Note that it's almost like it's reporting a memory address and modifying the class moved the address or something. Just thought I would share.

这很奇怪。有同事问了java中myArray.hashCode()的实现。我以为我知道,但后来我进行了一些测试。检查下面的代码。我注意到的奇怪想法是,当我写出第一个 sys 时,结果是不同的。请注意,这几乎就像是在报告内存地址并修改类移动了地址或其他内容。只是想我会分享。

int[] foo = new int[100000];
java.util.Random rand = new java.util.Random();

for(int a = 0; a < foo.length; a++) foo[a] = rand.nextInt();

int[] bar = new int[100000];
int[] baz = new int[100000];
int[] bax = new int[100000];
for(int a = 0; a < foo.length; a++) bar[a] = baz[a] = bax[a] = foo[a];

System.out.println(foo.hashCode() + " ----- " + bar.hashCode() + " ----- " + baz.hashCode() +  " ----- " + bax.hashCode());

// returns 4097744 ----- 328041 ----- 2083945 ----- 2438296
// Consistently unless you modify the class.  Very weird
// Before adding the comments below it returned this:
// 4177328 ----- 4097744 ----- 328041 ----- 2083945


System.out.println("Equal ?? " +
  (java.util.Arrays.equals(foo, bar) && java.util.Arrays.equals(bar, baz) &&
  java.util.Arrays.equals(baz, bax) && java.util.Arrays.equals(foo, bax)));

回答by MahdeTo

The java.lang.ArrayhashCodemethod is inherited from Object, which means the hashcode depends on the reference. To get the hashcode based on the content of the array use Arrays.hashCode.

java.lang.ArrayhashCode方法继承自Object,这意味着哈希码取决于引用。要根据数组的内容获取哈希码,请使用Arrays.hashCode.

Beware though its a shallow hashcode implementation. A deep implementation is also present Arrays.deepHashCode.

尽管它是一个浅层的哈希码实现,但要小心。一个深入的实现也存在Arrays.deepHashCode

回答by erickson

Arrays use the default hash code, which is based on memory location (but it isn't necessarily thememory location, since it's only an intand all memory addresses won't fit). You can see this by also printing the result of System.identityHashCode(foo).

数组使用基于内存位置的默认哈希码(但它不一定内存位置,因为它只是一个int并且所有内存地址都不适合)。您还可以通过打印System.identityHashCode(foo).

Arrays are only equalif they are the same, identical array. So, array hash codes will only be equal, generally, if they are the same, identical array.

数组仅equal当它们是相同的、相同的数组时。所以,数组散列码只会相等,通常,如果它们是相同的,相同的数组。

回答by James

The default implementation for Object.hashCode() is indeed to return the pointer value of the object, although this is implementation dependent. For instance, a 64-bit JVM may take the pointer and XOR and high and low order words together. Subclasses are encouraged to override this behavior if it makes sense.

Object.hashCode() 的默认实现确实是返回对象的指针值,尽管这取决于实现。例如,64 位 JVM 可以将指针和 XOR 以及高位和低位字放在一起。如果有意义,鼓励子类覆盖此行为。

However, it does not make sense to perform equality comparisons on mutatable arrays. If an element changes, then the two are no longer equal. To maintain the invariant that the same array will always return the same hashCode no matter what happens to its elements, arrays do not override the default hashcode behavior.

但是,对可变数组执行相等比较没有意义。如果一个元素发生变化,则两者不再相等。为了保持不变,即无论其元素发生什么变化,相同的数组将始终返回相同的 hashCode,数组不会覆盖默认的 hashcode 行为。

Note that java.util.Arrays provides a deepHashCode() implementation for when hashing based on the contents of the array, rather than the identity of the array itself, is important.

请注意,java.util.Arrays 提供了 deepHashCode() 实现,当基于数组内容而不是数组本身的身份进行散列时,这很重要。

回答by Carl Pritchett

I agree with using java.util.Arrays.hashCode (or the google guava generic wrapper Objects.hashcode) but be aware that this can cause issues if you are using Terracotta - see this link

我同意使用 java.util.Arrays.hashCode(或谷歌番石榴通用包装器 Objects.hashcode),但请注意,如果您使用 Terracotta,这可能会导致问题 - 请参阅此链接