Java 如何制作 ArrayList 的单独副本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1330288/
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
How to make a separated copy of an ArrayList?
提问by 5YrsLaterDBA
Possible Duplicate:
Java: how to clone ArrayList but also clone its items?
I have a sample program like the following:
我有一个示例程序,如下所示:
ArrayList<Invoice> orginalInvoice = new ArrayList<Invoice>();
//add some items into it here
ArrayList<Invoice> copiedInvoice = new ArrayList<Invoice>();
copiedInvoice.addAll(orginalInvoice);
I thought I can modify items inside the copiedInvoice
and it will not affect these items inside originalInoice
. But I was wrong.
我以为我可以修改里面的项目copiedInvoice
并且不会影响里面的这些项目originalInoice
。但是我错了。
How can I make a separated copy / clone of an ArrayList
?
如何制作一个单独的副本/克隆ArrayList
?
Thanks
谢谢
采纳答案by Adamski
Yes that's correct - You need to implement clone()
(or another suitable mechanism for copying your object, as clone()
is considered "broken" by many programmers). Your clone()
method should perform a deep copy of all mutable fields within your object. That way, modifications to the cloned object will not affect the original.
是的,这是正确的 - 您需要实现clone()
(或其他合适的机制来复制您的对象,因为clone()
许多程序员认为这是“破坏”的)。您的clone()
方法应该执行对象中所有可变字段的深层复制。这样,对克隆对象的修改不会影响原始对象。
In your example code you're creating a second ArrayList
and populating it with references to the same objects, which is why changes to the object are visible from both List
s. With the clone approach your code would look like:
在您的示例代码中,您正在创建第二个ArrayList
并使用对相同对象的引用填充它,这就是为什么从两个List
s都可以看到对对象的更改。使用克隆方法,您的代码将如下所示:
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());
}
EDIT: To clarify, the above code is performing a deep copyof the original List
whereby the new List
contains references to copies of the original objects. This contrasts to calling ArrayList.clone()
, which performs a shallow copy
of the List
. In this context a shallow copy creates a new List
instance but containing references to the original objects.
编辑:为了澄清,上面的代码正在执行原始对象的深层副本,List
其中新对象List
包含对原始对象副本的引用。与此相反,以调用ArrayList.clone()
,它执行shallow copy
的List
。在这种情况下,浅拷贝创建一个新List
实例,但包含对原始对象的引用。
回答by Lucky
If you are storing mutable objects into the ArrayList, you will need to copy each object when you copy the ArrayList. Otherwise, the new ArrayList will still hold the original references.
如果要将可变对象存储到 ArrayList 中,则在复制 ArrayList 时需要复制每个对象。否则,新的 ArrayList 仍将保留原始引用。
However if you're storing immutable objects, it's fine to use:
但是,如果您要存储不可变对象,则可以使用:
ArrayList copiedInvoice = new ArrayList(originalInvoice);
ArrayList copiedInvoice = new ArrayList(originalInvoice);
回答by OscarRyz
I thought I can modify items inside the copiedInvoice and it will not affect these itmes inside originalInoice.
我以为我可以修改 CopyInvoice 中的项目,并且不会影响 originalInoice 中的这些项目。
This happens because what gets copied is the reference variable and not the object it self.
发生这种情况是因为复制的是引用变量而不是它本身的对象。
Hence you end up with two "references" pointing to the same object.
因此,您最终会得到两个指向同一个对象的“引用”。
If you need to copy the whole object you may need to clone it.
如果您需要复制整个对象,您可能需要克隆它。
But you might have problems if you don't clone the object internal attributes if they happen to be other objects.
但是如果你不克隆对象内部属性,如果它们碰巧是其他对象,你可能会遇到问题。
For instance the following class definition won't give you any problem.
例如,以下类定义不会给您带来任何问题。
public class Something {
private int x;
private int y;
private String stringObject;
}
If you create a copy of that, you would copy the current values of its attributes and that's it.
如果您创建它的副本,您将复制其属性的当前值,仅此而已。
But if your class do have another object inside you might consider to clone it too.
但是如果你的类里面有另一个对象,你也可以考虑克隆它。
class OtherSomething {
Something something;
private int x;
}
If you do the following:
如果您执行以下操作:
Something shared = new Something();
OtherSomething one = new OtherSomething();
OtherSomething two = new OtherSomething();
one.something = shared;
two.something = shared;
In this case, both one and two have the same reference variable to the same shared "something" and changing the value in one would affect the other.
在这种情况下,一个和两个都具有指向相同共享“某物”的相同引用变量,并且更改一个中的值会影响另一个。
That's why it is much simpler/better/easier to use immutable objects.
这就是为什么使用不可变对象更简单/更好/更容易的原因。
If you need to change the value of an immutable object you just create a new one with the correct value.
如果您需要更改不可变对象的值,您只需创建一个具有正确值的新对象。
回答by Dave
Take a look at ByteArrayOutputStream and ByteArrayInputStream. If all of your classes implement Serializable, then you can make a copy using the above mentioned classes.
看看 ByteArrayOutputStream 和 ByteArrayInputStream。如果您的所有类都实现了 Serializable,那么您可以使用上述类进行复制。