如何在Java中克隆泛型列表?

时间:2022-10-30 15:03:30

I have an ArrayList<String> that I'd like to return a copy of. ArrayList has a clone method has the following signature:

我有一个ArrayList ,我想返回一个副本。ArrayList有一个克隆方法有以下签名:

public Object clone()

After I call this method, how do I cast the returned Object back to ArrayList<String>?

调用此方法后,如何将返回的对象转换回ArrayList ?

14 个解决方案

#1


52  

ArrayList newArrayList = (ArrayList) oldArrayList.clone();

#2


283  

Why would you want to clone? Creating a new list usually makes more sense.

你为什么要克隆?创建一个新的列表通常更有意义。

List<String> strs;
...
List<String> newStrs = new ArrayList<>(strs);

Job done.

工作。

#3


20  

This is the code I use for that:

这是我使用的代码:

ArrayList copy = new ArrayList (original.size());
Collections.copy(copy, original);

Hope is usefull for you

希望对你是有用的

#4


16  

Be advised that Object.clone() has some major problems, and its use is discouraged in most cases. Please see Item 11, from "Effective Java" by Joshua Bloch for a complete answer. I believe you can safely use Object.clone() on primitive type arrays, but apart from that you need to be judicious about properly using and overriding clone. You are probably better off defining a copy constructor or a static factory method that explicitly clones the object according to your semantics.

请注意Object.clone()有一些主要的问题,大多数情况下不建议使用它。请参阅Joshua Bloch的“有效Java”中的项目11,以获得完整的答案。我相信您可以安全地在原始类型数组上使用Object.clone(),但除此之外,您还需要谨慎地使用和覆盖克隆。您最好定义一个复制构造函数或静态工厂方法,根据您的语义显式克隆对象。

#5


15  

With Java 8 it can be cloned with a stream.

使用Java 8,可以用流克隆它。

import static java.util.stream.Collectors.toList;

...

List<AnObject> clone = myList.stream().collect(toList());

#6


14  

I think this should do the trick using the Collections API:

我认为使用集合API可以达到这个目的:

Note: the copy method runs in linear time.

注意:复制方法以线性时间运行。

//assume oldList exists and has data in it.
List<String> newList = new ArrayList<String>();
Collections.copy(newList, oldList);

#7


5  

I find using addAll works fine.

我发现使用addAll很有效。

ArrayList(String) copy = new ArrayList(String)();
copy.addAll(original);

parentheses are used rather than the generics syntax

使用圆括号而不是泛型语法。

#8


5  

If you want this in order to be able to return the List in a getter it would be better to do:

如果您希望这样做,以便能够以getter方式返回列表,那么最好这样做:

ImmutableList.copyOf(list);

#9


2  

Be very careful when cloning ArrayLists. Cloning in java is shallow. This means that it will only clone the Arraylist itself and not its members. So if you have an ArrayList X1 and clone it into X2 any change in X2 will also manifest in X1 and vice-versa. When you clone you will only generate a new ArrayList with pointers to the same elements in the original.

克隆数组列表时要非常小心。java中的克隆是浅显的。这意味着它将只克隆Arraylist本身,而不是它的成员。如果你有一个ArrayList X1并将它复制到X2, X2中的任何变化也会在X1中显现,反之亦然。克隆时,只会生成一个新的ArrayList,其中包含指向原始元素的指针。

#10


2  

My function to clone a List with type:

我的功能克隆一个列表与类型:

public static <T extends Object> List<T> cloneList(List<T> list) {
    return ((List<T>) ((ArrayList<T>) list).clone());
}

#11


2  

This should also work:

这也应该工作:

ArrayList<String> orig = new ArrayList<String>();
ArrayList<String> copy = (ArrayList<String>) orig.clone()

#12


2  

To clone a generic interface like java.util.List you will just need to cast it. here you are an example:

克隆一个通用接口,如java.util。列出您只需要对它进行强制转换。这里有一个例子:

List list = new ArrayList();
List list2 = ((List) ( (ArrayList) list).clone());

It is a bit tricky, but it works, if you are limited to return a List interface, so anyone after you can implement your list whenever he wants.

这有点棘手,但如果您被限制返回一个列表接口,那么您之后的任何人都可以随时实现您的列表。

I know this answer is close to the final answer, but my answer answers how to do all of that while you are working with List -the generic parent- not ArrayList

我知道这个答案很接近最终答案,但我的答案是,当你在处理列表时——泛型父类——而不是ArrayList时——如何完成所有这些

#13


1  

ArrayList first = new ArrayList ();
ArrayList copy = (ArrayList) first.clone ();

#14


0  

I am not a java professional, but I have the same problem and I tried to solve by this method. (It suppose that T has a copy constructor).

我不是java专业人士,但是我有同样的问题,我尝试用这种方法来解决。(假设T有一个复制构造函数)

 public static <T extends Object> List<T> clone(List<T> list) {
      try {
           List<T> c = list.getClass().newInstance();
           for(T t: list) {
             T copy = (T) t.getClass().getDeclaredConstructor(t.getclass()).newInstance(t);
             c.add(copy);
           }
           return c;
      } catch(Exception e) {
           throw new RuntimeException("List cloning unsupported",e);
      }
}

#1


52  

ArrayList newArrayList = (ArrayList) oldArrayList.clone();

#2


283  

Why would you want to clone? Creating a new list usually makes more sense.

你为什么要克隆?创建一个新的列表通常更有意义。

List<String> strs;
...
List<String> newStrs = new ArrayList<>(strs);

Job done.

工作。

#3


20  

This is the code I use for that:

这是我使用的代码:

ArrayList copy = new ArrayList (original.size());
Collections.copy(copy, original);

Hope is usefull for you

希望对你是有用的

#4


16  

Be advised that Object.clone() has some major problems, and its use is discouraged in most cases. Please see Item 11, from "Effective Java" by Joshua Bloch for a complete answer. I believe you can safely use Object.clone() on primitive type arrays, but apart from that you need to be judicious about properly using and overriding clone. You are probably better off defining a copy constructor or a static factory method that explicitly clones the object according to your semantics.

请注意Object.clone()有一些主要的问题,大多数情况下不建议使用它。请参阅Joshua Bloch的“有效Java”中的项目11,以获得完整的答案。我相信您可以安全地在原始类型数组上使用Object.clone(),但除此之外,您还需要谨慎地使用和覆盖克隆。您最好定义一个复制构造函数或静态工厂方法,根据您的语义显式克隆对象。

#5


15  

With Java 8 it can be cloned with a stream.

使用Java 8,可以用流克隆它。

import static java.util.stream.Collectors.toList;

...

List<AnObject> clone = myList.stream().collect(toList());

#6


14  

I think this should do the trick using the Collections API:

我认为使用集合API可以达到这个目的:

Note: the copy method runs in linear time.

注意:复制方法以线性时间运行。

//assume oldList exists and has data in it.
List<String> newList = new ArrayList<String>();
Collections.copy(newList, oldList);

#7


5  

I find using addAll works fine.

我发现使用addAll很有效。

ArrayList(String) copy = new ArrayList(String)();
copy.addAll(original);

parentheses are used rather than the generics syntax

使用圆括号而不是泛型语法。

#8


5  

If you want this in order to be able to return the List in a getter it would be better to do:

如果您希望这样做,以便能够以getter方式返回列表,那么最好这样做:

ImmutableList.copyOf(list);

#9


2  

Be very careful when cloning ArrayLists. Cloning in java is shallow. This means that it will only clone the Arraylist itself and not its members. So if you have an ArrayList X1 and clone it into X2 any change in X2 will also manifest in X1 and vice-versa. When you clone you will only generate a new ArrayList with pointers to the same elements in the original.

克隆数组列表时要非常小心。java中的克隆是浅显的。这意味着它将只克隆Arraylist本身,而不是它的成员。如果你有一个ArrayList X1并将它复制到X2, X2中的任何变化也会在X1中显现,反之亦然。克隆时,只会生成一个新的ArrayList,其中包含指向原始元素的指针。

#10


2  

My function to clone a List with type:

我的功能克隆一个列表与类型:

public static <T extends Object> List<T> cloneList(List<T> list) {
    return ((List<T>) ((ArrayList<T>) list).clone());
}

#11


2  

This should also work:

这也应该工作:

ArrayList<String> orig = new ArrayList<String>();
ArrayList<String> copy = (ArrayList<String>) orig.clone()

#12


2  

To clone a generic interface like java.util.List you will just need to cast it. here you are an example:

克隆一个通用接口,如java.util。列出您只需要对它进行强制转换。这里有一个例子:

List list = new ArrayList();
List list2 = ((List) ( (ArrayList) list).clone());

It is a bit tricky, but it works, if you are limited to return a List interface, so anyone after you can implement your list whenever he wants.

这有点棘手,但如果您被限制返回一个列表接口,那么您之后的任何人都可以随时实现您的列表。

I know this answer is close to the final answer, but my answer answers how to do all of that while you are working with List -the generic parent- not ArrayList

我知道这个答案很接近最终答案,但我的答案是,当你在处理列表时——泛型父类——而不是ArrayList时——如何完成所有这些

#13


1  

ArrayList first = new ArrayList ();
ArrayList copy = (ArrayList) first.clone ();

#14


0  

I am not a java professional, but I have the same problem and I tried to solve by this method. (It suppose that T has a copy constructor).

我不是java专业人士,但是我有同样的问题,我尝试用这种方法来解决。(假设T有一个复制构造函数)

 public static <T extends Object> List<T> clone(List<T> list) {
      try {
           List<T> c = list.getClass().newInstance();
           for(T t: list) {
             T copy = (T) t.getClass().getDeclaredConstructor(t.getclass()).newInstance(t);
             c.add(copy);
           }
           return c;
      } catch(Exception e) {
           throw new RuntimeException("List cloning unsupported",e);
      }
}