哪些流操作使用CONCURRENT
,IMMUTABLE
和NONNULL
Spliterator特征?他们每个人如何帮助这些行动?
我不会问这些标志是什么,这可以在文档中轻松找到。我询问哪些操作使用它们以及如何使用它们。
答案 0 :(得分:2)
首先,您应明确区分您在此处询问Spliterator
特征,这些特征取决于Stream的源;因为例如CONCURRENT
还有(UNORDERED
,IDENTITY_FINISH
和Collectors
。
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
报告IMMUTABLE
和ConcurrentHashMap
报告NONNULL
例如。)
另一方面,这些标志可以在将来使用 - 如果您知道源不能包含空元素(NONNULL
),显然您可以跳过一些空检查或定义某个状态< / em>带有null。我无法想到CONCURRENT
或IMMUTABLE
的任何示例,但可能会有这样的例子。
例如,在UNORDERED
和CONCURRENT
收集器(!= 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
特征,那么分词符将另外具有SIZED
和SUBSIZED
特征:< / 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
非SIZED
和SUBSIZED
的Spliterators并行化程度很低,因此当您编写自己的并发集合时,最好编写自定义spliterator而不依赖于默认的spliterator实现。