Java 10中Stream API不可变集合

18-09-24 banq
         

不可变数据结构能够应对高并发,无锁并发,JDK10提供Stream API不可变集合。

默认情况下,大多数Stream API集合代表可变的集合策略 - 但是如果想要将元素收集到不可变数据结构会发生什么?

首先想到的是将一个不可变集合的实例传递给Collectors.toCollection()集合,但它是一条死路,因为提供的集合是......不可变的,并且在创建之后无法更改:


Stream.of(42).collect(Collectors.toCollection(List::of));

// result
java.lang.UnsupportedOperationException
at ...ImmutableCollections.uoe(ImmutableCollections.java:71)
at ...ImmutableCollections$AbstractImmutableList.add(ImmutableCollections.java:77)
at ...stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at ...stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411)

从技术上讲,如果Collections / Stream API是以不可变的方式设计的,那么这不会是一个问题。

幸运的是,在JDK 10之前,对上述问题的实用解决方案非常简单。可以像往常一样简单地收集Stream,然后通过利用collectAndThen集合将结果转换为不可修改的结构:

var unmodifiableList = Stream.of(42)
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));



Java 10以后专用的本地Collector放到了桌面上,使得使用体验更加顺畅:
toUnmodifiableList()
toUnmodifiableMap()
toUnmodifiableSet()

以上所有都返回了JDK 9中引入的新的不可变实现。


var collect = Stream.of(42)
.collect(Collectors.toUnmodifiableList());


Java 10 Immutable/Unmodifiable Stream API Collecto