Java中ArrayList按条件过滤推荐用Stream API的filter()生成新列表,或用removeIf()原地删除;前者不改原集合,后者修改原集合且线程安全。

Java 中 ArrayList 按条件过滤元素,核心是借助 Stream API(推荐,简洁安全)或传统循环(兼容老版本、逻辑清晰)。直接修改原集合需谨慎,避免并发修改异常。
用 Stream.filter() 筛选并生成新列表
这是最常用、函数式风格的方式。filter() 接收一个 Predicate,返回满足条件的新 List(原 ArrayList 不变)。
- 确保 JDK 版本 ≥ 8
- 调用 stream() → filter(条件) → collect(Collectors.toList())
- 条件写在 lambda 表达式里,比如 x -> x > 10 或 user -> user.isActive()
示例:筛选出偶数
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
List<Integer> evens = list.stream()
.filter(x -> x % 2 == 0)
.collect(Collectors.toList()); // [2, 4]
用 removeIf() 原地删除不满足条件的元素
如果想直接修改原 ArrayList,可用 removeIf() —— 它内部安全处理迭代,不会抛 ConcurrentModificationException。
立即学习“Java免费学习笔记(深入)”;
- 传入 Predicate,删除所有 不满足 条件的元素(注意语义是“移除不符合的”,不是“保留符合的”)
- 操作后原列表被修改,无需重新赋值
示例:移除所有负数
ArrayList<Integer> nums = new ArrayList<>(Arrays.asList(-2, -1, 0, 1, 2)); nums.removeIf(x -> x < 0); // nums 变为 [0, 1, 2]
手动遍历 + 迭代器删除(兼容 JDK 7 及更早)
若项目不能升级 JDK,或需在遍历中做复杂判断,可用 Iterator 的 remove() 方法。
- 绝对不能用 for-each 或普通 for 循环调用 list.remove(),否则报 ConcurrentModificationException
- 必须用 iterator.remove(),它能同步维护内部状态
示例:删除字符串长度小于 3 的元素
ArrayList<String> words = new ArrayList<>(Arrays.asList("a", "to", "be", "or"));
Iterator<String> it = words.iterator();
while (it.hasNext()) {
if (it.next().length() < 3) {
it.remove();
}
} // words 变为 ["be", "or"]
过滤后转回 ArrayList(如需可变类型)
Stream.collect() 默认返回 ArrayList 吗?不一定 —— Collectors.toList() 返回的是实现类不确定的 List(通常是 ArrayList,但不保证)。如需明确是 ArrayList:
- 用 Collectors.toCollection(ArrayList::new)
- 或对结果强转(不推荐,有风险)
- 或 new ArrayList(streamResult)
稳妥写法:
List<String> filtered = list.stream()
.filter(s -> s.startsWith("A"))
.collect(Collectors.toCollection(ArrayList::new));


















