为了账号安全,请及时绑定邮箱和手机立即绑定

Java数组HashCode实现

/ 猿问

Java数组HashCode实现

炎炎设计 2019-11-15 10:47:47

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


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)));


查看完整描述

3 回答

?
慕姐4208626

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


请注意,尽管它是一个浅哈希码实现。一个深层的实现也存在Arrays.deepHashCode。


查看完整回答
反对 回复 2019-11-15
?
冉冉说

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


数组仅equal在它们相同,相同时才是数组。因此,通常,如果数组哈希码相同,则它们将等于数组。


查看完整回答
反对 回复 2019-11-15
?
慕虎7371278

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


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


请注意,java.util.Arrays提供了deepHashCode()实现,在这种情况下,基于数组内容而不是数组本身的标识进行哈希运算很重要。


查看完整回答
反对 回复 2019-11-15

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信