ArrayList的subList()返回原列表的动态视图而非副本,修改子列表会直接影响原列表,且原列表变动可能导致子列表失效;需用new ArrayList(list.subList(from, to))获取安全副本。

Java 中 ArrayList 的 subList() 方法可以快速获取子列表,但它返回的不是新 ArrayList,而是一个视图(View)——底层仍指向原列表,修改子列表会直接影响原列表,这点必须特别注意。
subList() 基本用法
调用方式:list.subList(fromIndex, toIndex),其中:
- fromIndex 是起始索引(包含),从 0 开始
- toIndex 是结束索引(不包含),必须 ≤ 原列表 size()
- 若索引越界(如负数、fromIndex > toIndex、toIndex > size()),抛出
IndexOutOfBoundsException
示例:
ArrayList<String> list = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "e")); List<String> sub = list.subList(1, 4); // ["b", "c", "d"]子列表是“活”的视图,不是副本
subList() 返回的是原 ArrayList 的动态视图,不是独立副本:
立即学习“Java免费学习笔记(深入)”;
- 在子列表中添加/删除元素 → 原列表同步变化(可能引发
ConcurrentModificationException) - 修改原列表(如 add/remove)→ 子列表可能失效,后续操作抛出
ConcurrentModificationException - 对子列表调用
clear()或removeAll()→ 真实删除原列表对应位置的元素
例如:
sub.add("x"); // list 变成 ["a", "b", "c", "d", "x", "e"] list.remove(0); // sub 失效,再访问 sub.size() 会抛异常安全使用 subList 的常见做法
如需真正独立的子列表副本,应显式构造新 ArrayList:
-
new ArrayList(list.subList(from, to))—— 最常用、最安全 - Java 10+ 可用
List.copyOf(list.subList(from, to))(不可变副本) - 若仅遍历读取,且生命周期短于原列表,可直接用 subList,避免额外开销
注意:不要长期缓存 subList 返回的对象,尤其在多线程或原列表可能被修改的场景下。
其他易踩坑点
-
subList()返回的 List 不支持add(null)等某些操作?错——它支持所有 List 接口方法,但行为受原列表约束 - 子列表的
indexOf()、contains()正常工作;但retainAll()会修改原列表 - 序列化 subList 会失败(它未实现
Serializable),而 new ArrayList(...) 后可序列化


















