java list无法添加类然后更改原始类而不更改列表中的副本

时间:2012-05-08 01:00:15

标签: java arraylist

所以我主要使用C ++编程,而java与c ++非常相似。 我已经创建了一个列表命令

 List<Item> stuff =new ArrayList<Item>();

其中Item是一个基本上存储数据的自定义类。 我从文本文件中获取信息并将其存储到Item。 然后我使用stuff.add来获取项目类。 然后我使用命令擦除项类中的所有数据,并看到它还删除了列表中的所有数据。 基本上我想知道是否有办法添加类的副本而不是类本身的地址。

编辑: 所以我发现尽管重新初始化项目类也解决了我的问题。

2 个答案:

答案 0 :(得分:1)

您希望在将项目添加到列表之前克隆该项目。该列表只包含您创建的原始项目的引用。因此,当您改变项目时,列表中的项目也会受到影响(它是同一个对象)。

如果您要“断开”放入列表中的项目,则可以先clone。您的item类需要实现Cloneable并覆盖clone()方法。如果Item中只有原语,那么你可以简单地执行:

public Object clone()
{
  return super.clone();
}

如果Item中有其他对象,则默认克隆操作只会生成浅拷贝,并且您需要使克隆方法更广泛,以便它使深拷贝。从Javadoc for Object.clone():

  

按照惯例,此方法返回的对象应独立于此对象(正在克隆)。要实现此独立性,可能需要在返回之前修改super.clone返回的对象的一个​​或多个字段。通常,这意味着复制包含被克隆对象的内部“深层结构”的任何可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含原始字段或对不可变对象的引用,那么通常情况下,super.clone返回的对象中的任何字段都不需要修改。

答案 1 :(得分:1)

在Java中,对象引用就像C ++中的指针一样。没有“复制构造函数”的概念。当您将某些内容添加到列表中,然后在将其添加到列表后更改项目时,您已经注意到了这一点。

通常在Java中,每次向列表中添加新的new时,都会使用Item创建新的while (...) { Item i = new Item(...); stuff.add(i); } 。如下所示:

Item i = new Item();
while (...) {
    i.foo = ...;
    stuff.add(i);
}

而不是

{{1}}

上面的第二个示例将多次将相同的对象添加到列表中。