哪些流操作使用`CONCURRENT`,`IMMUTABLE`和`NONNULL` Spliterator特性?

时间:2017-08-15 20:52:17

标签: java java-stream spliterator

哪些流操作使用CONCURRENTIMMUTABLENONNULL Spliterator特征?他们每个人如何帮助这些行动?

我不会问这些标志是什么,这可以在文档中轻松找到。我询问哪些操作使用它们以及如何使用它们。

2 个答案:

答案 0 :(得分:2)

首先,您应明确区分您在此处询问Spliterator特征,这些特征取决于Stream的;因为例如CONCURRENT还有(UNORDEREDIDENTITY_FINISHCollectors

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的直接1对1映射,但仍未使用它们。

目前(我已经搜索了jdk-8和9个来源),两者都没有被利用 - 但仍然被Spliterators的一些实现报告(Arrays报告IMMUTABLEConcurrentHashMap报告NONNULL例如。)

另一方面,这些标志可以在将来使用 - 如果您知道源不能包含空元素(NONNULL),显然您可以跳过一些空检查或定义某个状态< / em>带有null。我无法想到CONCURRENTIMMUTABLE的任何示例,但可能会有这样的例子。

例如,在UNORDEREDCONCURRENT收集器(!= Spliterator属性)的当前实现下,执行{{1}时未调用combiner }。例如:

toConcurrentMap

不会调用Set.of("one", "two", "das", "dasda") .stream() .parallel() .collect(Collectors.toConcurrentMap(Function.identity(), String::length)); - 因为没有必要。

可以针对您提到的3个特征中的任何一个进行这些优化。例如,您可以阅读this其中combiner已更改java 8与java 9中StreamOpFlag.ORDERED的结果

答案 1 :(得分:1)

在Java 8中,流操作不使用这3个特征。这可以通过在Java源代码中搜索这些常量来检查。

但是,CONCURRENT特性可能会在您编写自己的集合时影响并行流的行为。如果您从集合中创建Spliterator并且报告CONCURRENT特征,那么分词符将另外具有SIZEDSUBSIZED特征:< / p>

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特征,则分词器不再是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

SIZEDSUBSIZED的Spliterators并行化程度很低,因此当您编写自己的并发集合时,最好编写自定义spliterator而不依赖于默认的spliterator实现。