将Two Dimensional ArrayList复制为新的

问题描述 投票:3回答:4

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

任何人都知道这是什么原因,最好的解决方案是什么?

java arraylist
4个回答
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()));

0
投票

您的第一个和第二个示例之间的区别在于,在第二个示例中,您使用get()。此get()返回一个新变量,因此您将整数分配给它而不是原始的ArrayList

如果要分配值:

firstTwoDimList.set(1, new ArrayList<Integer>(Arrays.asList(0, 7)));

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()功能...


0
投票

您应该遍历firstTwoDimArray的第一个维度的大小,并将每个第二维度的新引用添加到secondTwoDimArray。即

for(int index = 0; index < firstTwoDimList.size(); index++) {
    secondTwoDimList.add(new ArrayList<Integer>(firstTwoDimList.get(index)));
}
© www.soinside.com 2019 - 2024. All rights reserved.