我希望b1
和b2
拥有自己的元素集,然后b1和b2应该在内存中有自己的元素,以便在修改b1 / b2时,其他元素不应受到影响
buffer
是包含许多元素的ArrayList
List<Integer> b1 = new ArrayList<Integer>(buffer.size()) ;
List<Integer> b2 = new ArrayList<Integer>(buffer.size()) ) ;
Collections.copy(b1, buffer);
Collections.copy(b2, buffer);
我得到了这个例外:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in dest at java.util.Collections.copy(Collections.java:531) at Trees.containsSumPrint(Trees.java:243) at Trees.main(Trees.java:125)
答案 0 :(得分:10)
ArrayList(int)
构造函数给出一个大小为0的List
,它只确保在需要重新分配底层数组之前可以添加n
个元素。
您可以更好地复制列表:
b1.addAll(buffer);
b2.addAll(buffer);
语义与第一次向每个数组添加buffer.size()
空值并调用Collections.copy(b1,buffer);
如果您想要深层复制(元素也被复制),您将必须单独处理每个元素
for(MyObject obj:buffer){
b1.add(obj.clone());
b2.add(obj.clone());
}
答案 1 :(得分:1)
Collections.copy(...)
javadoc说明了这一点:
“将一个列表中的所有元素复制到另一个列表中。操作后,目标列表中每个复制元素的索引将与源列表中的索引相同。目标列表必须至少与源列表一样长。如果它更长,则目标列表中的其余元素不受影响。“。
ArrayList(int)
构造函数创建一个空列表,其 capacity (不是大小!)由参数给出。
由于b1
最初为空,因此将非空列表复制到它(使用copy
)将失败,因为前提条件(以粗体显示)不成立(通常)。
基本上,Collections.copy(...)
是错误的使用方法。
你应该做的是:
List<Integer> b1 = new ArrayList<Integer>(buffer.size());
List<Integer> b2 = new ArrayList<Integer>(buffer.size());
b1.addAll(buffer);
b2.addAll(buffer);
我假设您确实想要创建列表元素的新实例。如果你这样做,我应该指出,创建Integer
个对象的新实例是浪费时间,因为Integer
(像其他包装类和String
)是一个不可变类。
答案 2 :(得分:1)
您需要每个元素的深层副本。没有标准的方法来实现这一点,因为深度复制可能涉及将嵌套引用复制到其他对象的(集合)。执行此操作的最佳方法是创建一个复制构造函数,java.lang.Integer碰巧有一个!所以我认为你应该这样做:
List<Integer> buffer = Arrays.asList(new Integer[] { 0, 1, 2, 3, 4 });
List<Integer> b1 = new ArrayList<Integer>();
List<Integer> b2 = new ArrayList<Integer>();
for (Integer element : buffer) {
b1.add(new Integer(element));
b2.add(new Integer(element));
}
这实际上创建了两个副本,每个目标列表中有一个副本。如果其中一个列表可能包含原始元素,请执行以下操作:
for (Integer element : buffer) {
b1.add(new Integer(element));
b2.add(element);
}
请注意,还存在可克隆的界面。我建议不要使用它,因为很容易在引用的类,集合和子类化中犯错误。复制构造函数更容易正确。请参阅this page进行一些确证。
编辑:重读时,也许你不想要深拷贝,在这种情况下你可以使用其他人描述的'addAll'方法。这将允许您创建相同对象实例的多个集合。然后,您可以修改一个集合中对象的内容/顺序,而不会影响其他集合。但是,如果您修改对象实例,这显然也会被所有其他集合反映出来。此外,StephenC理所当然地指出我上面的例子是坚果。我同意,人们永远不会像这样“深度复制”整数,但是对于包含我认为是问题的集合/引用的自定义对象是有意义的。