数组列表的所有元素在添加新元素时都会更改?

2022-09-04 05:30:46

首先,为无法提供任何源代码而道歉。我的项目非常大,链接所有内容是不切实际的,我无法缩小这个问题,这是非常烦人的。我将尽我所能在这里解释它。

我正在代码中的每个循环上动态创建类的新实例。此实例在循环中动态地赋予几个属性,例如“name”。在每个循环结束时,新生成的实例将添加到另一个第 3 类中保存的 ArrayList 中。

然而,问题在于,当添加新元素时,无论出于何种原因,所有以前的元素都会更改以完全匹配最新的元素。我的猜测是,ArrayList正在创建对动态创建的元素的引用,以便每当它更改时,它们都会更改,但我不知道如何解决此问题。

我将不胜感激任何建议,并再次为这个解释的质量道歉。我会发布您可能希望看到的任何特定代码片段

根据请求 - XmlHandler.java - http://pastebin.com/mGmWt1RD ParsedDataSet.java = http://pastebin.com/k1xb3KBe 内容.java = http://pastebin.com/UxiL2f9q

只是为了减少你的理解时间 - 该项目是一个epub阅读器。XMLHandler 是从另一个未显示的类中的 SAX 解析器调用的。XMLHandler 在 3 个不同的 XML 集中使用了 3 个不同的时间,因此存在一些混乱。

问题在于“toc”ArrayList。“toc”或 TableOfContents 保存稍后要引用的内容实例(未显示)。我正在尝试在“内容”的每个新实例中传递数据,然后将其传递到静态 ArrayList 中


答案 1

我见过人们多次报告这种问题,它总是归结为:你实际上不是在创建一个新实例,而是在循环的每次迭代中使用相同的实例。这是一个很容易犯的错误,特别是如果你来自一种具有不同复制语义的语言。有许多不同的方法可以犯这个错误;如果您编辑问题以显示循环代码,我相信我将能够解释正在发生的事情。

好了,现在您已经添加了代码:问题是在“内容”中,所有数据成员都标记为“静态”。在Java中,这意味着所有对象都有一个共享的变量 - 即,该变量对于每个对象具有相同的值。因此,实际上您正在创建许多要放入 ArrayList 的内容对象,但它们看起来都是一样的!从 Content 的数据成员中删除这些“静态”属性,即可完成所有设置。


答案 2

ArrayList只是存储元素的引用。确保您的代码如下所示:

ArrayList list = new ArrayList<>();
loop(...) {
    MyObject newOne = new MyObject();
    newOne.setXXX(xxx);
    list.add(newOne);
}

错误的代码:

ArrayList list = new ArrayList<>();
MyObject sameOne = new MyObject();
loop(...) {
    sameOne.setXXX(xxx);
    list.add(sameOne);
}