SubList返回原List的活视图而非独立副本,修改子列表会直接影响原列表,反之亦然;其为左闭右开区间,索引越界抛IndexOutOfBoundsException,需独立副本时应显式new ArrayList(subList)。

SubList 返回的是原 List 的视图,不是独立副本,修改子列表会直接影响原列表,反之亦然。
SubList 的基本用法和边界规则
调用 list.subList(fromIndex, toIndex) 可获取一个左闭右开的子列表(包含起始索引,不包含结束索引)。注意:两个索引都必须在 [0, list.size()] 范围内,否则抛出 IndexOutOfBoundsException。
- 若
fromIndex == toIndex,返回空的子列表(非 null) - 子列表支持增删改查,但所有操作最终都会反映到原列表上
- 子列表长度 =
toIndex - fromIndex
SubList 与原列表的强关联表现
SubList 是原 List 的“活视图”,底层共享同一存储结构(如 ArrayList 的 elementData 数组),因此:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 在子列表中调用
add()、remove()、set(),原列表同步变化,且原列表大小和元素位置可能随之调整 - 在原列表中修改子列表范围内的元素(如
set(i, x)),子列表立刻可见该变更 - 若在原列表中 在子列表范围外插入或删除元素,可能导致子列表后续操作抛出
ConcurrentModificationException(因为 modCount 不一致)
常见陷阱与安全使用建议
直接把 SubList 当作普通新列表使用容易出错,尤其在多线程或需要独立数据时:
立即学习“Java免费学习笔记(深入)”;
- 需要真正独立副本?请显式构造:
new ArrayList(list.subList(1, 4)) - 避免对 SubList 调用
clear()或大范围removeAll(),它会真实删掉原列表对应段的数据 - 不要缓存 SubList 长期使用——原列表一旦被结构性修改(如 add/remove),该 SubList 就失效
- 迭代 SubList 时,不要同时通过原列表修改其结构(哪怕改的是外面的位置),极易触发并发修改异常
一个直观示例
假设 list = [A, B, C, D, E],执行 sub = list.subList(1, 4) → sub = [B, C, D]:
-
sub.set(0, "X")→ 原列表变成[A, X, C, D, E] -
sub.add("Y")→ 原列表变成[A, X, C, D, Y, E],sub变为[X, C, D, Y] -
list.remove(0)→ 原列表变[X, C, D, Y, E],此时再访问sub.get(0)仍为"X";但若再调用sub.add("Z"),则抛出ConcurrentModificationException

















