所以我遇到的问题是在复制2d arraylist之后,从一个2d arraylist更改元素会影响另一个2d arraylist。我希望它们在记忆中完全分开。
第一个例子展示了它如何与1d arraylists一起正常工作......
import java.util.ArrayList;
public class QuickTest {
public static void main(String[] args) {
ArrayList<Integer> firstList = new ArrayList<>();
ArrayList<Integer> secondList = new ArrayList<>();
Integer counter = 2;
for(int arrI = 0; arrI < 4; arrI++, counter+=2){
firstList.add(counter);
}
secondList = new ArrayList<>(firstList);
System.out.println("firstList.get(2) = " + firstList.get(2));
System.out.println("secondList.get(2) = " + secondList.get(2));
firstList.set(2, 7);
System.out.println("firstList.get(2) = " + firstList.get(2));
System.out.println("secondList.get(2) = " + secondList.get(2));
}
}
预期产出:
注意第一个arraylist中的元素是如何更改的,但第二个arraylist元素没有更改。这很好,我们想要的。
现在尝试复制2d arraylists ......
import java.util.ArrayList;
public class QuickTest {
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> firstTwoDimList = new ArrayList<>();
ArrayList<ArrayList<Integer>> secondTwoDimList = new ArrayList<>();
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
Integer counter = 2;
for(int arrI = 0; arrI < firstTwoDimList.size(); arrI++, counter+=2){
firstTwoDimList.get(arrI).add(counter);
counter+=2;
firstTwoDimList.get(arrI).add(counter);
}
secondTwoDimList = new ArrayList<>(firstTwoDimList);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
firstTwoDimList.get(1).set(0, 7);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
}
}
意外输出:
任何人都知道这是什么原因,以及最佳解决方案是什么?
答案 0 :(得分:4)
这就是1D数组列表中的情况,就引用而言:
这就是2D数组列表中的情况:
这意味着当您使用以下方法复制数组列表时:
new ArrayList<>(someOldArrayList)
项目本身不会被复制,只会创建一个新的数组列表对象,引用旧数组列表中的所有项目。
在第二种情况下,您只更改数组列表2的项目,但第一个列表的索引1和第二个列表引用相同的数组列表2.
要解决此问题,您还需要复制第一个列表和第二个列表中的数组列表。一种方法:
secondList = new ArrayList<>(firstList.stream().map(x -> new ArrayList<>(x)).collect(Collectors.toList()));
答案 1 :(得分:0)
您的第一个和第二个示例之间的区别在于,在第二个示例中,您使用get()
。此get()
会返回一个新变量,因此您可以为其指定整数,而不是原始ArrayList
。
如果要分配值:
firstTwoDimList.set(1, new ArrayList<Integer>(Arrays.asList(0, 7)));
答案 2 :(得分:0)
您应该遍历firstTwoDimArray
第一维的大小,并将每个第二维的新引用添加到secondTwoDimArray
。即
for(int index = 0; index < firstTwoDimList.size(); index++) {
secondTwoDimList.add(new ArrayList<Integer>(firstTwoDimList.get(index)));
}
答案 3 :(得分:0)
我想我正在寻找像这样的东西......
import java.util.ArrayList;
public class QuickTest {
public static ArrayList<ArrayList<Integer>> getTwoDimArrListCopy(ArrayList<ArrayList<Integer>> original){
ArrayList<ArrayList<Integer>> copy = new ArrayList<>();
for (ArrayList<Integer> arr: original){
copy.add(new ArrayList<Integer>(arr));
}
return copy;
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> firstTwoDimList = new ArrayList<>();
ArrayList<ArrayList<Integer>> secondTwoDimList = new ArrayList<>();
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
Integer counter = 2;
for(int arrI = 0; arrI < firstTwoDimList.size(); arrI++, counter+=2){
firstTwoDimList.get(arrI).add(counter);
counter+=2;
firstTwoDimList.get(arrI).add(counter);
}
secondTwoDimList = getTwoDimArrListCopy(firstTwoDimList);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
firstTwoDimList.get(1).set(0, 7);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
}
}
我只是希望有一个内置库可以为我做getTwoDimArrListCopy()
函数...