【问题标题】:Why does the hashCode() of an ArrayList change every time you add a new element?为什么每次添加新元素时 ArrayList 的 hashCode() 都会发生变化?
【发布时间】:2016-06-12 16:10:26
【问题描述】:

根据我对ArrayList的理解,默认容量是10,当超过10时,它会创建一个具有新容量的新对象等等..

所以出于好奇,我输入了以下程序来检查hashcode() 是否有ArrayList 对象:

public class TestCoreJava {

    public static void main(String [] args){

        ArrayList al = new ArrayList();

        for(int i=0;i<15;i++){

            al.add("Temp"+i);
            System.out.println("Hashcode for "+i+" element "+al.hashCode());
        }
    }
}

根据上述情况,当我没有为ArrayList设置初始容量时,默认值为10。 因此,在添加第 11 个元素时,它将创建一个新对象并增加 ArrayList 的容量。

当我打印ArrayList 对象的哈希码时,它每次都会给出一个新的hashcode()

下面是o/p:

Hashcode for 0 element 80692955
Hashcode for 1 element -1712792766
Hashcode for 2 element -1476275268
Hashcode for 3 element 1560799875
Hashcode for 4 element 1220848797
Hashcode for 5 element -727700028
Hashcode for 6 element -1003171458
Hashcode for 7 element -952851195
Hashcode for 8 element 607076959
Hashcode for 9 element 1720209478
Hashcode for 10 element -6600307
Hashcode for 11 element -1998096089
Hashcode for 12 element 690044110
Hashcode for 13 element -1876955640
Hashcode for 14 element 150430735

根据默认容量的概念,直到第 10 个元素它应该打印相同的hashcode(),因为在此之前不需要创建新对象,但事实并非如此。

【问题讨论】:

标签: java arraylist collections hashcode


【解决方案1】:

ArrayListhashCodehashCodes 存储在ArrayList 中的所有元素的函数,因此它不会随着容量的变化而变化,它会随着您添加或删除一个元素或以改变其 hashCode 的方式改变其中一个元素。

这是 Java 8 的实现(实际上是在 AbstractList 中实现的):

public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

顺便说一句,这是List 接口的hashCode() 的Javadoc 中出现的确切代码:

int java.util.List.hashCode()

返回此列表的哈希码值。列表的哈希码定义为以下计算的结果:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

【讨论】:

  • 这会产生哈希冲突。例如,如果 1+3 = 2+2 这意味着 2 个列表可能具有相同的哈希值。
  • @JavaMain 是的,这不是问题。实际上,在 Java 中,.hashCode() 方法应该为与.equals() 相等的两个对象提供相同的哈希码,但对于两个不同的对象,它不必给出不同的哈希码,即使它更好.
【解决方案2】:

List 实现中的hashCodedefined in terms of the hashCode of its elements。这意味着要使 ArrayList 成为符合 List 的实现,它的 hashCode 必须在其内容更改时更改。

更一般地说:对于可变对象,hashCode 应该在它们发生变化时发生变化,使它们不会 equal 回到以前的状态。

您似乎假设它使用了Objectdefault hashCode,事实并非如此。

此外,即使 ArrayList 没有实现 hashCode,如果重新分配内部数组,ArrayList 的默认哈希码(也称为 identity hash code)也不会改变,因为 @ 987654337@ 对象本身保持不变,只是内部数组对象(您无法直接访问)将被替换为新对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-24
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多