Java 将二维ArrayList复制为新的

Java 将二维ArrayList复制为新的,java,arraylist,Java,Arraylist,所以我遇到的问题是在复制2d arraylist之后,从一个2d arraylist更改元素会影响另一个2d arraylist。我希望他们在记忆中完全分开 第一个示例显示了它如何正确处理1d ArrayList import java.util.ArrayList; public class QuickTest { public static void main(String[] args) { ArrayList<Integer> firstList =

所以我遇到的问题是在复制2d arraylist之后,从一个2d arraylist更改元素会影响另一个2d arraylist。我希望他们在记忆中完全分开

第一个示例显示了它如何正确处理1d ArrayList

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));
    }
}
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));
    }
}
import java.util.ArrayList;
公共类快速测试{
公共静态void main(字符串[]args){
ArrayList firstList=新的ArrayList();
ArrayList secondList=新的ArrayList();
整数计数器=2;
对于(int arrI=0;arrI<4;arrI++,计数器+=2){
添加(计数器);
}
secondList=新的ArrayList(firstList);
System.out.println(“firstList.get(2)=”+firstList.get(2));
System.out.println(“secondList.get(2)=”+secondList.get(2));
第一组(2,7);
System.out.println(“firstList.get(2)=”+firstList.get(2));
System.out.println(“secondList.get(2)=”+secondList.get(2));
}
}
预期产出:

请注意,第一个arraylist中的元素是如何更改的,而第二个arraylist元素则没有更改。这很好,也是我们想要的

现在尝试复制2d ArrayList

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));
    }
}
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));
    }
}
import java.util.ArrayList;
公共类快速测试{
公共静态void main(字符串[]args){
ArrayList


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

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

如果要指定值,请执行以下操作:

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

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

for(int index = 0; index < firstTwoDimList.size(); index++) {
    secondTwoDimList.add(new ArrayList<Integer>(firstTwoDimList.get(index)));
}
for(int index=0;index
这就是1D数组列表案例中发生的情况,以引用的形式:


以下是2D阵列列表案例中发生的情况:

这意味着,当您使用以下命令复制阵列列表时:

new ArrayList<>(someOldArrayList)
新建ArrayList(someOldArrayList)
项目本身不会被复制,只会创建一个新的数组列表对象,引用旧数组列表中的所有项目

在第二种情况下,您只需要更改数组列表2的项目,但第一个列表和第二个列表的索引1引用相同的数组列表2

要解决此问题,还需要复制第一个列表和第二个列表中的数组列表。一种方法是:

secondList = new ArrayList<>(firstList.stream().map(x -> new ArrayList<>(x)).collect(Collectors.toList()));
secondList=newarraylist(firstList.stream().map(x->newarraylist(x)).collect(Collectors.toList());

我想我在找这样的东西

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));
    }
}
import java.util.ArrayList;
公共类快速测试{
公共静态ArrayList getTwoDimArrListCopy(ArrayList原件){
ArrayList copy=新建ArrayList();
用于(ArrayList arr:原件){
复制。添加(新阵列列表(arr));
}
返回副本;
}
公共静态void main(字符串[]args){
ArrayList firstTwoDimList=新的ArrayList();
ArrayList secondTwoDimList=新的ArrayList();
add(newarraylist());
add(newarraylist());
add(newarraylist());
整数计数器=2;
对于(int arrI=0;arrI

我只是希望有一个内置的库可以为我实现
gettwodmarrlistcopy()
函数…

Java是通过引用传递的,这可能就是您看到的原因。但是,为什么您要处理列表列表?是的,我正在处理列表列表列表(我的程序中最多有4d ArrayList).因此,我认为创建一个传递值的副本将是更好的解决方案…因此,假设我创建了一百万个副本,并开始更改所有列表的值…我将不得不为每个副本使用该行?是否有更简单的方法将其复制为一个新数组,而不必担心更改其他列表?嗯,您没有更改其他数组。假设您的副本仍然引用原始变量是错误的。您可以通过比较对象来测试这一点,如
object1==object2
。这将比较实际引用,在您的情况下,将返回
false
,这是好的(意味着这不是同一个对象)。因此,您的复制很好。只是您分配新变量的方式是错误的。我意识到由于元素不同,它们将是不同的对象(这就是为什么我希望在原始程序中将它们分开)。我也理解您的解决方案(将值设置为新变量,不更改内存中保存的内容…即为该变量分配新内存插槽)。我只是希望在创建副本时有一种更简单的方法,它将创建一个传递值,而不是传递引用。因此,两个ArrayList在内存中是完全分开的。我想最简单的方法是创建一个
twoDimArrCopy()