java 为什么每次添加新元素时 ArrayList 的 hashCode() 都会改变?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35702631/
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-11-03 00:28:29  来源:igfitidea点击:

Why does the hashCode() of an ArrayList change every time you add a new element?

javaarraylistcollectionshashcode

提问by suyash

As per my understanding of ArrayList, the default capacity is 10 and when it grows beyond 10, it will create a new object with new capacity and so on..

根据我对 的理解ArrayList,默认容量是 10,当它增长超过 10 时,它将创建一个具有新容量的新对象,依此类推。

So out of curiosity, I typed following program to check hashcode()for ArrayListobject:

因此,出于好奇,我输入下面的程序来检查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());
        }
    }
}

According to above scenario, when I am not setting Initial capacity for ArrayListthe default would be 10. So while adding 11th element, it will create a new object and increase the capacity for ArrayList.

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

When I print the hashcode for ArrayListobject, it is giving a new hashcode()each time.

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

Following is the o/p:

以下是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

According to the concept of default capacity, till 10th element it should have printed same hashcode()as no new object needs to be created until that point, but it is not the case.

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

回答by Eran

The hashCodeof ArrayListis a function of the hashCodes of all the elements stored in the ArrayList, so it doesn't change when the capacity changes, it changes whenever you add or remove an element or mutate one of the elements in a way that changes its hashCode.

hashCodeArrayList是一个功能hashCode都存储在该元件S1 ArrayList,所以当容量的变化,它的变化当添加或删除元素或改变其的hashCode办法元素发生变异一个它不会改变。

Here's the Java 8 implementation (it's actually implemented in AbstractList) :

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

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

BTW, this is the exact code that appears in the Javadoc of hashCode()of the Listinterface :

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

int java.util.List.hashCode()

Returns the hash code value for this list. The hash code of a list is defined to be the result of the following calculation:

int java.util.List.hashCode()

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

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

回答by Joachim Sauer

The hashCodeof Listimplementations is defined in terms of the hashCodeof its elements. This means that for ArrayListto be a conforming Listimplementation it's hashCodemustchange when its content changes.

所述hashCodeList实施方式是在条款中定义hashCode它的元素的。这意味着ArrayList要成为一致的List实现,它hashCode必须在其内容更改时更改。

More generally: for mutable objects, the hashCodeshould change whenever they change in a way that would make them not equalto their previous state.

更一般地说:对于可变对象,hashCode只要它们以一种不会使它们equal回到以前状态的方式发生变化,就应该更改。

You seem to be assuming that it uses the default hashCodeof Object, which is not the case.

你似乎是假设它使用默认hashCodeObject,这是情况并非如此。

Additionally, even if ArrayListdid not implement hashCode, the default hash code (also known as the identity hash code) of an ArrayListwould not change if the internal array was re-allocated, as the ArrayListobject itself stays the same, just the internal array object (that you don't get direct access to) will be replaced with a new one.

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