目标:将两个集合合并为(第三个)集合
我喜欢这个解决方案的流畅性(只需要一个语句):
Stream.concat(collection.stream(), anotherCollection.stream())
.collect(/* some Collector */)
然而,我最新的 PR 提交虽然已被接受并合并,但已被编辑以替换该行(请注意,现在的语句数量是原来的两倍):
Collection</* some type */> mergedCollection = new /* Collection implementation */<>(collection);
mergedCollection.addAll(anotherCollection);
我不想打扰进行更改的维护者,所以我决定询问 SO 社区
用
Stream.concat()
合并集合有什么缺点吗?
使用
Stream#concat
的主要缺点是它只接受 2 个流。它的作用正如其所说:将两个流连接成一个。
如果您需要连接三个或更多流,请使用
Stream#of
,但是,它带有平面映射:
final List<Object> list = Stream.of(collection1, collection2, collection3)
.flatMap(Collection::stream)
.toList();
平面映射本身并不坏,但依赖于流的存在来进行串联。如果存在大量嵌套结构,这并不理想,因为结果是仅为平面映射而临时创建不必要数量的流,并且较大的数量可能会影响性能。
该怎么办? 最好的选择是
Stream#mapMulti
,以避免过多创建额外的流:
final List<Object> list = Stream.of(collection1, collection2, collection3)
.mapMulti(Collection::forEach)
.toList();
为了更好地理解它,这里是使用 lambda 表达式而不是方法引用的扩展表示法:
final List<Object> list = Stream.of(collection1, collection2, collection3)
.mapMulti((collection, consumer) -> collection.forEach(consumer))
.toList();
这是从 Java 16 开始发明的,我写了另一个关于它的使用的answer。