[英]Which stream operations use `CONCURRENT`,`IMMUTABLE` and `NONNULL` Spliterator characteristics?
Which stream operations use CONCURRENT
, IMMUTABLE
and NONNULL
Spliterator characteristics? 哪些流操作使用
CONCURRENT
, IMMUTABLE
和NONNULL
分隔符特征? How does each of them help in those operations? 他们每个人如何帮助这些行动?
I'm not asking what those flags are, this can be found easly in the documantation. 我不是在问那些标志是什么,可以在文档中轻松找到。 I'm asking which operations use them and how.
我在问哪些操作使用它们以及如何使用它们。
First, you should make a clear distinction that you are asking about Spliterator
characteristics here and these depend on the source of the Stream; 首先,您应该明确区分您在此处询问的
Spliterator
特性,这些取决于Stream的来源 。 because there are also ( CONCURRENT
, UNORDERED
and IDENTITY_FINISH
for Collectors
for example). 因为也有(例如,
Collectors
CONCURRENT
, UNORDERED
和IDENTITY_FINISH
)。
There is a comment in StreamOpFlag
saying: 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, ...
As far as I understand these are not a direct 1 to 1 mapping with the ones from Spliterator, but still they are not used. 据我了解,这些不是与Spliterator的直接一对一映射,但仍未使用。
At the moment (and I've searched the jdk-8 and 9 sources), neither are leveraged - but still are reported by some implementations of Spliterators ( Arrays
report IMMUTABLE
and ConcurrentHashMap
reports NONNULL
for example). 目前 (并且我已经搜索了jdk-8和9来源),两者都没有被利用-但是仍然由Spliterators的一些实现报告(例如,
Arrays
报告IMMUTABLE
而ConcurrentHashMap
报告NONNULL
)。
These flags could be used in the future on the other hand - if you know that a source can not contain null elements ( NONNULL
), obviously you can skip some null checks or define some state with a null. 另一方面,这些标志可能会在将来使用-如果您知道某个源不能包含null元素(
NONNULL
),则显然可以跳过某些null检查或使用null定义某些状态 。 I can't think of any examples for CONCURRENT
or IMMUTABLE
, but there might be such. 我想不出任何
CONCURRENT
或IMMUTABLE
示例,但是可能有这样的示例。
For example under the current implementation for an UNORDERED
and CONCURRENT
collector (!= Spliterator
properties), the combiner
is not called when you do toConcurrentMap
. 例如,在当前实现下,用于
UNORDERED
和CONCURRENT
收集器(!= Spliterator
属性),在执行toConcurrentMap
时不调用combiner
。 For example: 例如:
Set.of("one", "two", "das", "dasda")
.stream()
.parallel()
.collect(Collectors.toConcurrentMap(Function.identity(), String::length));
will not call the combiner
- since there is no need to. 不会调用
combiner
-因为没有必要。
Optimizations like these could be made for any of the 3 characteristics that you have mentioned. 可以针对您提到的3个特征中的任何一个进行此类优化。 For example you can read this where
StreamOpFlag.ORDERED
has changed the result of findFirst
in java 8 vs java 9 例如,您可以阅读以下内容 ,其中
StreamOpFlag.ORDERED
更改了Java 8 vs Java 9中findFirst
的结果
In Java 8, the stream operations use neither of these 3 characteristics. 在Java 8中,流操作既不使用这三个特征。 This can be checked by searching these constants in the Java sources.
可以通过在Java源代码中搜索这些常量来检查。
However, the CONCURRENT
characteristic may affect the behaviour of parallel streams when you write your own collection. 但是,当您编写自己的集合时,
CONCURRENT
特性可能会影响并行流的行为。 If you create a Spliterator
from a collection and not report the CONCURRENT
characteristic, then the spliterator will additionally have SIZED
and SUBSIZED
characteristics: 如果您从集合中创建一个
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
But if you report the CONCURRENT
characteristic, then the spliterator is not SIZED
anymore: 但是,如果你报告
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
Spliterators that are not SIZED
and SUBSIZED
are poorly parallelized, so when you write you own concurrent collection, it is better to write a custom spliterator and not rely on the default spliterator implementation. 非
SIZED
和SUBSIZED
器并行SUBSIZED
程度较差,因此在编写自己的并发集合时,最好编写自定义拆分器,而不依赖于默认的拆分器实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.