当前位置: 首页 > 知识库问答 >
问题:

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

许明朗
2023-03-14

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

所以出于好奇,我键入以下程序来检查ArrayList对象的hashcode()

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时,它每次都会给出一个新的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(),因为在那之前不需要创建新对象,但事实并非如此。

共有2个答案

穆智刚
2023-03-14

List实现的hashCode是根据其元素的hashCode定义的。这意味着对于ArrayList来说,要成为符合要求的List实现,其内容更改时,其hashCode必须更改。

更一般地说:对于可变对象,hashCode应该在它们以某种方式改变时改变,使它们不等于它们以前的状态。

您似乎假设它使用了对象的默认哈希代码,但事实并非如此。

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

苏涛
2023-03-14

ArrayListhashCode是存储在ArrayList中的所有元素的hashCode的函数,因此容量改变时它不会改变,只要添加或删除一个元素,或者以改变其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。列表hashCode()

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

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
 类似资料:
  • 问题内容: 据我了解,默认容量为10,并且当其超过10时,它将创建具有新容量的新对象,依此类推。 因此,出于好奇,我输入下面的程序来检查的对象: 根据上述情况,当我未将默认初始容量设置为10时,因此在添加第11个元素时,它将创建一个新对象并增加的容量。 当我打印对象的哈希码时,每次都会给出一个新值。 以下是o / p: 根据默认容量的概念,直到第10个元素之前,都应打印相同的内容,因为在此之前不需

  • 问题内容: 首先,对无法提供任何源代码表示歉意。我的项目很大,将所有内容链接起来都是不切实际的,而且我还无法缩小非常烦人的问题。我将尽力在这里进行解释。 我在代码的每个循环中动态创建类的新实例。在循环中会为该实例动态地提供几个属性,例如’name’。在每个循环的最后,新生成的实例将添加到另一个第3类中保存的ArrayList中。 但是,问题在于,无论出于何种原因添加新元素时,所有先前的元素都会更改

  • 问题内容: 我们有多个线程调用上。 我的理论是,当由两个线程同时调用时,实际上仅将要添加的两个对象之一添加到。这看似合理吗? 如果是这样,您如何解决呢?使用类似吗? 问题答案: 对于ArrayList上的两个线程同时调用add时发生的情况,没有任何保证的行为。但是,根据我的经验,两个对象的添加都很好。与列表相关的大多数线程安全问题在添加/删除时都会处理迭代。尽管如此,我强烈建议不要将Vanilla

  • 我有一个pom。依赖项/插件的xml文件错误。每次我添加新的依赖项时,它都会给出与版本相关的错误。目前,它给出了与Eureka服务器相关的错误。 在pom.xml中添加Eureka命名服务器依赖项后的错误消息 项目生成错误:“依赖项”。附属国。组织版。springframework。云:Spring的云启动器尤里卡:罐子不见了。 pom.xml文件:

  • 问题内容: 当尝试使用maven构建Web应用程序时,当我的Internet连接处于连接状态时,通常会出现以下错误。 我的问题是,为什么在较早构建同一应用程序时,maven总是每次都要下载。 我的配置每次Maven都要下载时可能出什么毛病? 以下是我尝试离线构建时遇到的错误: 问题答案: 在您的元素(或项目的父级或公司父级POM)中查找该元素。它看起来像下面的样子。 注意元素。该示例告诉Maven

  • 问题内容: 我有这个android代码,它从服务器中获取一个JSON并从该JSON填充一个ArrayList,我在onresponse空隙内检查了ArrayList“ meals”的大小,它给了我1,但是当我在StringRequest对象后对其进行检查时,我得到了0个项目。进餐在全局范围内定义,并在oncreateview函数内部进行初始化代码: 问题答案: 这里的问题是关于了解任务如何工作的。