ArrayList 无直接截取方法,需用 subList(from, to) 获取动态视图(左闭右开),修改互通;要独立副本须 new ArrayList<>(subList()) 或 List.copyOf()。

Java 中的 ArrayList 本身没有直接的“截取子集合”方法,但可以通过 subList(int fromIndex, int toIndex) 获取一个**视图(view)**,它是一个与原列表联动的、可读写的子列表。
用 subList 获取子列表(推荐)
subList 返回的是原 ArrayList 的一个动态视图,不是独立副本。修改子列表会直接影响原列表,反之亦然。
- 索引范围:左闭右开 ——
fromIndex包含,toIndex不包含(类似字符串的substring) - 索引必须合法:
0 ≤ fromIndex ≤ toIndex ≤ size(),否则抛IndexOutOfBoundsException - 返回值类型是
List<E>,不是ArrayList;如需ArrayList,需显式构造
示例:
ArrayList<String> list = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "e"));
List<String> sub = list.subList(1, 4); // ["b", "c", "d"]
sub.set(0, "x"); // 修改后,原 list 变为 ["a", "x", "c", "d", "e"]
获取真正独立的子集合(不联动原列表)
如果需要一份独立副本(修改不影响原列表),不能只用 subList,要配合构造器或 new ArrayList<>():
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
-
new ArrayList<>(list.subList(from, to))—— 最常用、简洁 - JDK 10+ 可用
List.copyOf(list.subList(from, to))(返回不可变副本) - 手动遍历添加(不推荐,冗余)
示例:
ArrayList<Integer> original = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); ArrayList<Integer> copy = new ArrayList<>(original.subList(0, 3)); // [1, 2, 3] copy.add(99); // original 不受影响
注意:subList 视图的常见陷阱
这个视图很轻量,但也带来几个关键限制:
- 不能调用
add()、remove()、clear()等结构性修改方法(除非原列表也支持且未被并发修改),否则抛UnsupportedOperationException或ConcurrentModificationException - 视图生命周期依赖原列表 —— 如果原列表被修改(如
add/remove),再访问子列表可能出错 - 序列化时不会单独保存子列表内容,它只是引用原列表的一段
小技巧:安全封装截取逻辑
写个工具方法,兼顾安全性与易用性:
public static <T> ArrayList<T> slice(ArrayList<T> list, int from, int to) {
if (list == null) return new ArrayList<>();
int size = list.size();
int start = Math.max(0, Math.min(from, size));
int end = Math.max(start, Math.min(to, size));
return new ArrayList<>(list.subList(start, end));
}
这样能自动处理越界,避免运行时异常,适合频繁截取场景。

















