Stream.concat 是静态方法,用于将两个独立 Stream 顺序拼接成新流,原流不变,不自动去重或排序;基本用法为传入两个 Stream 参数。

Java 中 Stream.concat 是静态方法,用于将两个独立的 Stream 合并成一个新流,原流不会被修改,也不会自动去重或排序,只是顺序拼接。
基本用法:传入两个 Stream 参数
Stream.concat(Stream extends T> a, Stream extends T> b) 要求两个流元素类型兼容(通常是相同类型),返回一个新的流,先遍历 a,再遍历 b。
- 两个流都必须是非空或可为空;若任一为
null,会抛出NullPointerException - 合并后的新流需手动消费(如
forEach)或终端操作,否则不触发执行 - 注意:不能直接对已关闭或已消费过的流再次 concat,会抛出
IllegalStateException
常见使用场景示例
比如合并两个字符串列表的流:
List<String> list1 = Arrays.asList("a", "b");
List<String> list2 = Arrays.asList("c", "d");
Stream<String> merged = Stream.concat(list1.stream(), list2.stream());
merged.forEach(System.out::println); // 输出 a, b, c, d
也可以合并不同来源的流,如数组流 + 集合流、生成流 + 常量流等,只要类型一致即可。
立即学习“Java免费学习笔记(深入)”;
合并多个流的技巧
Stream.concat 只接受两个参数,要合并三个及以上流,可用嵌套调用或更简洁的收集方式:
- 嵌套:
Stream.concat(Stream.concat(s1, s2), s3) - 推荐方式:用
Stream.of(s1, s2, s3).flatMap(Function.identity()),更易读且支持任意数量 - 注意 flatMap 内部仍会按顺序消费每个子流,效果等价于多次 concat
注意事项与避坑点
使用 Stream.concat 时容易忽略的关键细节:
- 流一旦被消费(如调用了
count()或forEach()),就不能再复用;concat 前请确保流未被提前终止 - 如果源是 I/O 流(如文件行流),concat 后仍需保证资源正确关闭,建议用 try-with-resources 包裹原始流
- 并行流 concat 后默认仍是并行流,但性能不一定提升,顺序依赖场景慎用并行


















