如何制作 ArrayList 的单独副本?

2022-09-01 12:40:29

可能的重复:
Java:如何克隆ArrayList,同时克隆其项目?

我有一个示例程序,如下所示:

ArrayList<Invoice> orginalInvoice = new ArrayList<Invoice>();

//add some items into it here

ArrayList<Invoice> copiedInvoice = new ArrayList<Invoice>();

copiedInvoice.addAll(orginalInvoice);


我以为我可以修改里面的项目,它不会影响里面的这些项目。但我错了。copiedInvoiceoriginalInoice

如何制作一个分离的副本/克隆?ArrayList

谢谢


答案 1

是的,这是正确的 - 你需要实现(或其他合适的机制来复制你的对象,因为许多程序员认为“损坏”)。您的方法应执行对象中所有可变字段的深度复制。这样,对克隆对象的修改不会影响原始对象。clone()clone()clone()

在示例代码中,您将创建第二个对象,并使用对相同对象的引用填充它,这就是为什么对对象的更改从两个中都可见的原因。使用克隆方法,您的代码将如下所示:ArrayListList

List<Foo> originalList = ...;

// Create new List with same capacity as original (for efficiency).
List<Foo> copy = new ArrayList<Foo>(originalList.size());

for (Foo foo: originalList) {
  copy.add((Foo)foo.clone());
}

编辑:为了澄清,上面的代码正在执行原始副本的深度复制,其中new包含对原始对象副本的引用。这与调用 形成对比,后者执行 a 的 .在此上下文中,浅层副本会创建一个新实例,但包含对原始对象的引用。ListListArrayList.clone()shallow copyListList


答案 2

如果要将可变对象存储到 ArrayList 中,则需要在复制 ArrayList 时复制每个对象。否则,新的 ArrayList 仍将保存原始引用。

但是,如果要存储不可变对象,则可以使用:

ArrayList copiedInvoice = new ArrayList(originalInvoice);