Java 如何克隆 ArrayList 并克隆其内容?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/715650/
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 clone ArrayList and also clone its contents?
提问by palig
How can I clone an ArrayList
and also clone its items in Java?
如何ArrayList
在 Java 中克隆并克隆其项目?
For example I have:
例如我有:
ArrayList<Dog> dogs = getDogs();
ArrayList<Dog> clonedList = ....something to do with dogs....
And I would expect that objects in clonedList
are not the same as in dogs list.
我希望对象clonedList
与狗列表中的对象不同。
采纳答案by Varkhan
You will need to iterate on the items, and clone them one by one, putting the clones in your result array as you go.
您将需要迭代这些项目,并一项一项地克隆它们,并在执行过程中将克隆项放入结果数组中。
public static List<Dog> cloneList(List<Dog> list) {
List<Dog> clone = new ArrayList<Dog>(list.size());
for (Dog item : list) clone.add(item.clone());
return clone;
}
For that to work, obviously, you will have to get your Dog
class to implement the Cloneable
interface and override the clone()
method.
为此,显然,您必须让您的Dog
类实现Cloneable
接口并覆盖该clone()
方法。
回答by Stephan202
You will need to clone the ArrayList
by hand (by iterating over it and copying each element to a new ArrayList
), because clone()
will not do it for you. Reason for this is that the objects contained in the ArrayList
may not implement Clonable
themselves.
您将需要ArrayList
手动克隆(通过迭代它并将每个元素复制到一个 new ArrayList
),因为clone()
不会为您完成。原因是包含在 中的对象ArrayList
可能无法实现Clonable
自己。
Edit: ... and that is exactly what Varkhan's code does.
编辑:...这正是 Varkhan 的代码所做的。
回答by cdmckay
I, personally, would add a constructor to Dog:
我个人会为 Dog 添加一个构造函数:
class Dog
{
public Dog()
{ ... } // Regular constructor
public Dog(Dog dog) {
// Copy all the fields of Dog.
}
}
Then just iterate (as shown in Varkhan's answer):
然后只需迭代(如 Varkhan 的回答所示):
public static List<Dog> cloneList(List<Dog> dogList) {
List<Dog> clonedList = new ArrayList<Dog>(dogList.size());
for (Dog dog : dogList) {
clonedList.add(new Dog(dog));
}
return clonedList;
}
I find the advantage of this is you don't need to screw around with the broken Cloneable stuff in Java. It also matches the way that you copy Java collections.
我发现这样做的好处是你不需要在 Java 中处理损坏的 Cloneable 东西。它还与您复制 Java 集合的方式相匹配。
Another option could be to write your own ICloneable interface and use that. That way you could write a generic method for cloning.
另一种选择是编写自己的 ICloneable 接口并使用它。这样你就可以编写一个通用的克隆方法。
回答by Fortyrunner
The other posters are correct: you need to iterate the list and copy into a new list.
其他海报是正确的:您需要迭代列表并复制到新列表中。
However... If the objects in the list are immutable - you don't need to clone them. If your object has a complex object graph - they will need to be immutable as well.
但是...如果列表中的对象是不可变的 - 您不需要克隆它们。如果您的对象具有复杂的对象图 - 它们也需要是不可变的。
The other benefit of immutability is that they are threadsafe as well.
不变性的另一个好处是它们也是线程安全的。
回答by Cojones
I think the current green answer is bad, why you might ask?
我认为目前的绿色答案很糟糕,你为什么要问?
- It can require to add a lot of code
- It requires you to list all Lists to be copied and do this
- 它可能需要添加大量代码
- 它要求您列出要复制的所有列表并执行此操作
The way serialization is also bad imo, you might have to add Serializable all over the place.
序列化的方式也很糟糕,您可能需要到处添加 Serializable 。
So what is the solution:
那么解决方法是什么:
Java Deep-Cloning library The cloning libraryis a small, open source (apache licence) java library which deep-clones objects. The objects don't have to implement the Cloneable interface. Effectivelly, this library can clone ANY java objects. It can be used i.e. in cache implementations if you don't want the cached object to be modified or whenever you want to create a deep copy of objects.
Java 深度克隆库 克隆库是一个小型的开源(Apache 许可)java 库,它可以深度克隆对象。这些对象不必实现 Cloneable 接口。实际上,这个库可以克隆任何 java 对象。如果您不希望缓存对象被修改,或者您想创建对象的深层副本,则可以在缓存实现中使用它。
Cloner cloner=new Cloner();
XX clone = cloner.deepClone(someObjectOfTypeXX);
Check it out at https://github.com/kostaskougios/cloning
回答by Andrew Coyte
Here is a solution using a generic template type:
这是使用通用模板类型的解决方案:
public static <T> List<T> copyList(List<T> source) {
List<T> dest = new ArrayList<T>();
for (T item : source) { dest.add(item); }
return dest;
}
回答by Rose Perrone
All standard collections have copy constructors. Use them.
所有标准集合都有复制构造函数。使用它们。
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original); //This does a shallow copy
clone()
was designed with several mistakes (see this question), so it's best to avoid it.
clone()
设计时有几个错误(请参阅此问题),因此最好避免它。
From Effective Java 2nd Edition, Item 11: Override clone judiciously
来自Effective Java 2nd Edition,第 11 条:明智地覆盖克隆
Given all of the problems associated with Cloneable, it's safe to say that other interfaces should not extend it, and that classes designed for inheritance (Item 17) should not implement it. Because of its many shortcomings, some expert programmers simply choose never to override the clone method and never to invoke it except, perhaps, to copy arrays. If you design a class for inheritance, be aware that if you choose not to provide a well-behaved protected clone method, it will be impossible for subclasses to implement Cloneable.
鉴于与 Cloneable 相关的所有问题,可以肯定地说其他接口不应该扩展它,并且设计用于继承的类(条目 17)不应该实现它。由于它的许多缺点,一些专家程序员只是选择从不覆盖 clone 方法并且从不调用它,除非可能复制数组。如果您为继承设计类,请注意,如果您选择不提供行为良好的受保护的克隆方法,子类将无法实现 Cloneable。
This book also describes the many advantages copy constructors have over Cloneable/clone.
本书还描述了复制构造函数相对于 Cloneable/clone 的许多优点。
- They don't rely on a risk-prone extralinguistic object creation mechanism
- They don't demand unenforceable adherence to thinly documented conventions
- They don't conflict with the proper use of final fields
- They don't throw unnecessary checked exceptions
- They don't require casts.
- 他们不依赖有风险的语言外对象创建机制
- 他们不要求不可强制地遵守没有记录的约定
- 它们与正确使用 final 字段不冲突
- 他们不会抛出不必要的检查异常
- 他们不需要演员表。
Consider another benefit of using copy constructors: Suppose you have a HashSet s
, and you want to copy it as a TreeSet
. The clone method can't offer this functionality, but it's easy with a conversion constructor: new TreeSet(s)
.
考虑使用复制构造函数的另一个好处:假设您有一个HashSet s
,并且您想将它复制为一个TreeSet
。clone 方法无法提供此功能,但使用转换构造函数很容易:new TreeSet(s)
.
回答by RN3KK Nick
for you objects override clone() method
为您的对象覆盖 clone() 方法
class You_class {
int a;
@Override
public You_class clone() {
You_class you_class = new You_class();
you_class.a = this.a;
return you_class;
}
}
and call .clone() for Vector obj or ArraiList obj....
并为 Vector obj 或 ArraiList obj 调用 .clone() ....
回答by sonida
Easy way by using commons-lang-2.3.jar that library of java to clone list
使用 commons-lang-2.3.jar 那个 java 库来克隆列表的简单方法
link download commons-lang-2.3.jar
How to use
如何使用
oldList.........
List<YourObject> newList = new ArrayList<YourObject>();
foreach(YourObject obj : oldList){
newList.add((YourObject)SerializationUtils.clone(obj));
}
I hope this one can helpful.
我希望这个可以有所帮助。
:D
:D
回答by pacheco
The package import org.apache.commons.lang.SerializationUtils;
包 import org.apache.commons.lang.SerializationUtils;
There is a method SerializationUtils.clone(Object);
有一个方法 SerializationUtils.clone(Object);
Example
例子
this.myObjectCloned = SerializationUtils.clone(this.object);