WMX · 随记
·Java· 3 分钟阅读

集合复制:新容器不一定带来新元素

复制 List 后修改元素,原列表仍然变化,是浅复制中常见的惊讶。容器独立和元素独立,需要分开判断。

▶ 本文含视频讲解
▶ 教学视频手动播放 · 英语讲解

Java Tutorial for Beginners

Java 基础课程作为语言背景复习;本文的特定 API、版本行为和边界条件以正文及文档为准。此为外部原版课程,多篇笔记可能共用;未剪辑为本文专属视频。

播放器需要能访问 YouTube 的网络;若这里无法加载,可打开原视频。本文与本地图解仍可独立阅读。

Java 系列概览:类型与值、状态与资源、边界验证
Java 系列概览:类型与值、状态与资源、边界验证 点击图片查看大图 ↗

问题从哪里出现

复制 List 后修改元素,原列表仍然变化,是浅复制中常见的惊讶。容器独立和元素独立,需要分开判断。

理解核心机制

new ArrayList<>(source) 会创建新容器,但元素引用仍共享。List.copyOf 返回不可修改的列表并拒绝 null 元素;它也不深度复制元素对象。根据元素的可变性决定是否需要逐项复制。

动手做一个小实验

Java 17 或更新版本;将示例保存为 Demo.java,执行 javac Demo.java 后运行 java Demo。

Java13 行 · 可横向滚动
import java.util.ArrayList;
import java.util.List;
public class Demo {
    public static void main(String[] args) {
        var value = new StringBuilder("a");
        var original = new ArrayList<>(List.of(value));
        var copy = new ArrayList<>(original);
        copy.get(0).append("b");
        copy.clear();
        System.out.println(original.get(0));
        System.out.println(original.size());
    }
}

适用边界与常见误区

不可修改列表只限制容器操作,不能冻结 StringBuilder 等元素。Collections.unmodifiableList 还是一个视图,原容器的变化也可能反映出来。

继续练习

把元素换成 String,再换成嵌套 List,比较修改外层和修改内层的效果;为接口返回值写下“快照”或“视图”的承诺。

参考资料

阅读相关官方文档或原始资料 ↗

← 返回文章归档