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

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 ----- 2083945System.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

TA贡献1852条经验 获得超7个赞

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


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


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

TA贡献1877条经验 获得超1个赞

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


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


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

TA贡献1802条经验 获得超4个赞

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


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


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


查看完整回答
反对 回复 2019-11-15
  • 3 回答
  • 0 关注
  • 1487 浏览

添加回答

举报

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