![](/img/trans.png)
[英]Doesn't Stream.parallel() update the characteristics of spliterator?
[英]Which stream operations use `CONCURRENT`,`IMMUTABLE` and `NONNULL` Spliterator characteristics?
哪些流操作使用CONCURRENT
, IMMUTABLE
和NONNULL
分隔符特征? 他们每个人如何帮助这些行动?
我不是在问那些标志是什么,可以在文档中轻松找到。 我在问哪些操作使用它们以及如何使用它们。
首先,您应该明确区分您在此处询问的Spliterator
特性,这些取决于Stream的来源 。 因为也有(例如, Collectors
CONCURRENT
, UNORDERED
和IDENTITY_FINISH
)。
StreamOpFlag
有一条评论说:
// The following Spliterator characteristics are not currently used but a
// gap in the bit set is deliberately retained to enable corresponding
// stream flags if//when required without modification to other flag values.
//
// 4, 0x00000100 NONNULL(4, ...
// 5, 0x00000400 IMMUTABLE(5, ...
// 6, 0x00001000 CONCURRENT(6, ...
// 7, 0x00004000 SUBSIZED(7, ...
据我了解,这些不是与Spliterator的直接一对一映射,但仍未使用。
目前 (并且我已经搜索了jdk-8和9来源),两者都没有被利用-但是仍然由Spliterators的一些实现报告(例如, Arrays
报告IMMUTABLE
而ConcurrentHashMap
报告NONNULL
)。
另一方面,这些标志可能会在将来使用-如果您知道某个源不能包含null元素( NONNULL
),则显然可以跳过某些null检查或使用null定义某些状态 。 我想不出任何CONCURRENT
或IMMUTABLE
示例,但是可能有这样的示例。
例如,在当前实现下,用于UNORDERED
和CONCURRENT
收集器(!= Spliterator
属性),在执行toConcurrentMap
时不调用combiner
。 例如:
Set.of("one", "two", "das", "dasda")
.stream()
.parallel()
.collect(Collectors.toConcurrentMap(Function.identity(), String::length));
不会调用combiner
-因为没有必要。
可以针对您提到的3个特征中的任何一个进行此类优化。 例如,您可以阅读以下内容 ,其中StreamOpFlag.ORDERED
更改了Java 8 vs Java 9中findFirst
的结果
在Java 8中,流操作既不使用这三个特征。 可以通过在Java源代码中搜索这些常量来检查。
但是,当您编写自己的集合时, CONCURRENT
特性可能会影响并行流的行为。 如果您从集合中创建一个Spliterator
并且未报告CONCURRENT
特征,则该拆分器将另外具有SIZED
和SUBSIZED
特征:
Collection<Integer> col = ...
Spliterator<Integer> s = Spliterators.spliterator(col, 0);
System.out.println(s.hasCharacteristics(Spliterator.SIZED)); // Prints true
System.out.println(s.hasCharacteristics(Spliterator.SUBSIZED)); // Prints true
但是,如果你报告CONCURRENT
的特点,那么spliterator不SIZED
了:
Collection<Integer> col = ...
Spliterator<Integer> s = Spliterators.spliterator(col, Spliterator.CONCURRENT);
System.out.println(s.hasCharacteristics(Spliterator.SIZED)); // Prints false
System.out.println(s.hasCharacteristics(Spliterator.SUBSIZED)); // Prints false
非SIZED
和SUBSIZED
器并行SUBSIZED
程度较差,因此在编写自己的并发集合时,最好编写自定义拆分器,而不依赖于默认的拆分器实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.