好的,我只想将List<String[]> list
复制到List<String[]> list2
。之后我会修改list2
&amp;中的对象。我希望它不会影响任何对象int list
。
String[] s={"1","2"};
List<String[]> list=new ArrayList<String[]>();
list.add(s);
List<String[]> list2=new ArrayList<String[]>(list);
Collections.copy(list2,list);
list2.get(0)[1]="3";
for (String[] strings : list) {
System.out.println(Arrays.toString(strings));
}
输出:[1, 3]
为什么我们改变list2
&amp;它会影响list1
吗?
怎么解决?
答案 0 :(得分:3)
Collections.copy()
不会执行深层复制。
它只是将元素从一个集合复制到另一个集合。它与ArrayList
构造函数基本相同,因此您无需同时调用它们。
两个列表中的第一个元素仍然引用同一个对象。因此,在运行代码时,您将修改两个列表中的数组。您可以迭代所有元素,并在每个列表项上使用Arrays.copyOf
。
这样的事情:
private List<String[]> deepCopy(List<String[]> list) {
List<String[]> copy = new ArrayList<String[]>(list.size());
for (String[] element : list) {
copy.add(Arrays.<String> copyOf(element, element.length));
}
return copy;
}
编辑: Java&lt; 1.6版本:
private List<String[]> deepCopy(List<String[]> list) {
List<String[]> copy = new ArrayList<String[]>(list.size());
for (String[] element : list) {
String[] elementCopy = new String[element.length];
System.arraycopy(element, 0, elementCopy, 0, element.length);
copy.add(elementCopy);
}
return copy;
}
答案 1 :(得分:1)
您要求的是复制集合和克隆它所拥有的所有对象。在您的情况下,您只有字符串列表。其他人已经为你提供了很好的答案。就像一张纸条。一般来说,这并不容易,因为没有通用的克隆对象的方法。因为集合中的每个对象都可以引用其他对象本身。这些对象可以进一步引用更多对象。所以这取决于你需要什么。
您是否只需要克隆集合中的对象,而不是那些对象引用的对象? 这称为“浅层复制”。
或者您是否需要将所有对象复制到对象参考树中。这称为“深度复制”。
或者您可能需要介于两者之间。这意味着您只需要复制某些对象。
你看,没有金色的子弹可以解决所有问题。这就是为什么它没有在通用集合类中实现。在某些情况下,如果您正在处理打开的文件句柄或其他系统资源,则甚至可能无法进行克隆。
但是你可以做的是让你的类实现Cloneable接口。在clone()方法中,您可以调用super.clone(),它已经为您进行了浅层克隆。除此之外的一切都需要由您自己实施。然后,您只需要为集合中的每个对象调用clone()以创建克隆对象。
这是如何实现Cloneable:
class MyClass implements Cloneable {
private int a;
private int b;
private MyClass c;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
调用clone()会给你一个MyClass对象的副本。这意味着 a 和 b 将是副本以及对象 c 的引用。但只有参考,而不是对象c本身。如果您需要,您需要执行以下操作:
@Override
public Object clone() throws CloneNotSupportedException {
MyClass clone = (MyClass)super.clone();
clone.c = (MyClass2)c.clone();
return clone;
}
以下是浅层和深层复制以及Cloneable接口的更详细说明:
http://javapapers.com/core-java/java-clone-shallow-copy-and-deep-copy/