addall()最直接,但需注意是否允许重复、原集合是否可变、null处理及泛型一致性;stream.concat()需collect才得list;collectionutils.union()名不副实且已弃用。

用 addAll() 最直接,但要注意是否允许重复和原集合是否可变
如果两个 List 都是 ArrayList 或其他支持修改的实现类,addAll() 是最常用方式。它把第二个集合所有元素追加到第一个集合末尾,返回 boolean 表示是否发生了实际添加(空集合不会触发修改)。
常见错误:对 Collections.unmodifiableList() 调用 addAll() 会抛出 UnsupportedOperationException;还有人误以为 addAll() 会去重——它完全不做任何判断,原样叠加。
- 若需去重,得先转成
Set再转回List,或手动遍历过滤 - 若不想修改原集合,必须新建一个目标
List,比如new ArrayList(list1),再调用addAll(list2) - 注意泛型一致性:两个
List<string></string>合并没问题,但List<object></object>和List<string></string>混用可能触发编译警告或运行时类型问题
Java 8 的 Stream.concat() 适合函数式风格,但别忘了收集
Stream.concat() 可以把两个 Stream 拼接成一个,但它本身不返回 List,只是中间操作。漏掉 collect(Collectors.toList()) 是新手高频错误,结果得到的是 Stream 而非想要的集合。
性能上,它会创建新对象,不修改原集合,适合只读场景;但如果集合很大,Stream 的开销(尤其是并行流误用)可能比直接 addAll() 高。
立即学习“Java免费学习笔记(深入)”;
Sylius开源电子商务平台是一个开源的 PHP 电子商务网站框架,基于 Symfony 和 Doctrine 构建,为用户量身定制解决方案。可管理任意复杂的产品和分类,每个产品可以设置不同的税率,支持多种配送方法,集成 Omnipay 在线支付。功能特点:前后端分离Sylius 带有一个强大的 REST API,可以自定义并与您选择的前端或您的微服务架构很好地配合使用。如果您是 Symfony
- 写法示例:
Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList()) - 如果 list1 或 list2 为
null,调用.stream()会直接抛NullPointerException,要提前判空 - 合并后顺序严格按 list1 + list2,和
addAll()一致,但底层迭代次数略多
用 Apache Commons Collections 的 CollectionUtils.union()?小心语义陷阱
CollectionUtils.union() 名字像“并集”,但实际行为取决于传入集合类型。对 List,它**不是去重合并**,而是类似 addAll();只有当两个参数都是 Set 时,才真正做数学意义上的并集。
更麻烦的是,它的返回类型是 Collection,不是 List,强转可能失败;而且该方法已标记为 @Deprecated(自 4.4 版起),官方推荐用 JDK 原生方案或 CollectionUtils.unionAsList() 替代。
- 想用就用
CollectionUtils.unionAsList(list1, list2),它返回List且保留重复 - 真要并集去重,请用
new ArrayList(new LinkedHashSet(list1))加手动 addAll,或改用Set作为中间容器 - 引入第三方库只为合并 List,往往得不偿失——除非项目已依赖 Commons Collections 且有其他用途
合并含 null 元素的 List 时,addAll() 和 Stream 表现不同
ArrayList.addAll() 允许添加 null,只要目标集合本身支持(比如 ArrayList 支持,但某些包装类如 Collections.checkedList() 可能拒绝)。而 Stream.concat() 在遇到 null 流时会立即抛 NullPointerException——因为 list.stream() 对 null list 本身就会失败。
所以如果数据源不可信,必须在合并前统一处理:Objects.requireNonNull(list1, "list1 must not be null"),或者用 Optional.ofNullable(list1).orElse(Collections.emptyList()) 提供兜底。
- 不要依赖
Stream.of(list1, list2).flatMap(List::stream).collect(...)来规避 null ——Stream.of(null)生成的是含一个null元素的 Stream,后续flatMap仍会崩在null.stream() - 若业务允许,用
list1 == null ? list2 : list2 == null ? list1 : ...显式分支更可控









