将Two Dimensional ArrayList复制为新的

时间:2017-12-19 02:17:40

标签: java arraylist

所以我遇到的问题是在复制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));
    }
}

预期产出:

enter image description here

注意第一个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));
    }
}

意外输出:

enter image description here

任何人都知道这是什么原因,以及最佳解决方案是什么?

4 个答案:

答案 0 :(得分:4)

这就是1D数组列表中的情况,就引用而言:

enter image description here

这就是2D数组列表中的情况:

enter image description here

这意味着当您使用以下方法复制数组列表时:

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()函数...