Guava的Iterables.concat()可惰性串联多个Iterable,不复制元素、不预加载内存,按需拉取并严格保序;支持任意数量参数及嵌套Iterable解包,API比Apache Commons更轻量直观。

直接用 Guava 的 Iterables.concat() 就能优雅串联多个零散集合的遍历逻辑,无需新建中间集合、不触发立即计算,真正实现“按需拉取”。Apache Commons Collections 也有类似能力,但 Guava 更轻量、API 更直观、与 Java Stream 兼容性更好。
用 Iterables.concat 合并多个 Iterable 实例
这是最常用也最推荐的方式。只要变量是 Iterable(包括 List、Set、自定义迭代器等),就能无缝拼接成一个逻辑上的单一遍历源:
- 所有入参保持原样,不复制元素,不预加载内存
- 返回的是惰性迭代器,只有调用
next()时才从当前子源取值;子源耗尽后自动切换下一个 - 支持任意数量参数,也支持传入
Iterable<Iterable<T>>(需配合Iterables.concat(Iterables))
示例:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
Iterable<String> a = Arrays.asList("a", "b");
Iterable<String> b = Sets.newHashSet("c", "d");
Iterable<String> c = ImmutableList.of("e");
Iterable<String> merged = Iterables.concat(a, b, c);
// 遍历时才逐个拉取:a→b→c,顺序严格保证
for (String s : merged) {
System.out.print(s); // 输出 abcde
}
处理嵌套结构或动态集合列表
当零散集合本身被装在一个 List<Iterable<T>> 或 Collection<Iterable<T>> 中时,不能直接传参给 concat(...),需先解包:
- 用
Iterables.concat(iterableOfIterables)—— 这是专为“集合的集合”设计的重载方法 - 确保外层容器本身也是
Iterable(如List、Set)即可,无需转成数组 - 若外层是普通
Collection,可直接传入;若为数组,先用Arrays.asList()包一层
示例:
List<Iterable<Integer>> chunks = new ArrayList<>(); chunks.add(Arrays.asList(1, 2)); chunks.add(Sets.newLinkedHashSet(Arrays.asList(3, 4))); chunks.add(ImmutableList.of(5)); Iterable<Integer> flat = Iterables.concat(chunks); // ✅ 正确解包
合并时跳过 null 或空集合
Iterables.concat() 本身不校验参数,传入 null 会抛 NullPointerException。实战中建议前置过滤:
- 用
Iterables.filter(iterables, Predicates.notNull())剔除 null 元素 - 对每个子集做非空判断:可用
Iterables.isEmpty()辅助,或封装工具方法统一跳过空/无效源 - 更简洁的做法是先用
Lists.newArrayList()收集有效源,再 concat
示例(安全合并):
List<Iterable<String>> sources = getSources(); // 可能含 null 或空
List<Iterable<String>> valid = Lists.newArrayList();
for (Iterable<String> src : sources) {
if (src != null && !Iterables.isEmpty(src)) {
valid.add(src);
}
}
Iterable<String> safeMerged = Iterables.concat(valid);
对比 Apache Commons Collections 的 CompositeIterator
Apache Commons Collections 提供了 CompositeIterator(位于 org.apache.commons.collections4.iterators),功能相似但使用略重:
- 需手动构造
CompositeIterator实例,并逐个addIterator() - 没有泛型推断友好型静态工厂,代码冗长
- 不支持
Iterable直接入参,必须是Iterator,常需先调.iterator() - Guava 的
Iterables.concat()在语义清晰度、链式扩展性(比如后续接filter、transform)上明显更优
除非项目已深度绑定 Commons Collections 且无法引入 Guava,否则优先选 Guava。

















