You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中修改子ArrayList为何会同步到原列表?如何避免该问题?

// "static void main" must be defined in a public class.
import java.util.*;
public class Main {
    static void func(ArrayList<ArrayList<Integer>> arr) {
        ArrayList<Integer> arr1 = new ArrayList();
        arr1.add(0);
        arr.add(arr1);
        arr1.set(0,5);
    }
    public static void main(String[] args) {
        ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>();
        func(arr);
        for(int i=0;i<arr.size();i++) {
            for(int j=0;j<arr.get(i).size();j++) {
                System.out.print(arr.get(i).get(j));
            }
            System.out.println();
        }
    }
}
问题解答

同步变更的原因

Java中ArrayList属于引用类型,执行arr.add(arr1)操作时,并没有把arr1的完整内容复制一份存入二维列表,只是把arr1指向的堆内存地址的引用存入了arr。
也就是说*arr1和arr中存储的第一个元素,指向的是堆内存中同一个ArrayList对象*,通过任意一个引用修改这个对象的内容,另一个引用访问到的自然是修改后的结果。

避免方案

往二维ArrayList中添加一维列表时,不要直接传入原对象的引用,传入原一维列表的副本即可。
当前场景下一维列表的元素是不可变的Integer类型,仅做浅拷贝就足够,修改添加逻辑为:

// 调用ArrayList的拷贝构造函数生成arr1的副本,存入arr
arr.add(new ArrayList<>(arr1));

如果后续一维列表存储的是自定义可变对象,还需要对每个元素做深拷贝,才能完全隔离原对象和副本的修改影响。

内容的提问来源于stack exchange,提问作者Vinayak Anil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:15:04