Java 哪些流操作使用'CONCURRENT'、'IMMUTABLE'和'NONNULL'拆分器特征?
哪些流操作使用了Java 哪些流操作使用'CONCURRENT'、'IMMUTABLE'和'NONNULL'拆分器特征?,java,java-stream,spliterator,Java,Java Stream,Spliterator,哪些流操作使用了并发、不可变和非空拆分器特性?他们每个人如何帮助这些行动 我不是问那些旗子是什么,这在文档中很容易找到。我在问哪些操作使用它们以及如何使用它们。在Java8中,流操作既不使用这三个特征,也不使用这三个特征。这可以通过在Java源代码中搜索这些常量来检查 但是,当您编写自己的集合时,并发特性可能会影响并行流的行为。如果从集合创建拆分器,并且不报告并发特征,则拆分器将另外具有大小和子项特征: Collection<Integer> col = ... Spliterat
并发
、不可变
和非空
拆分器特性?他们每个人如何帮助这些行动
我不是问那些旗子是什么,这在文档中很容易找到。我在问哪些操作使用它们以及如何使用它们。在Java8中,流操作既不使用这三个特征,也不使用这三个特征。这可以通过在Java源代码中搜索这些常量来检查 但是,当您编写自己的集合时,
并发
特性可能会影响并行流的行为。如果从集合创建拆分器
,并且不报告并发
特征,则拆分器将另外具有大小
和子项
特征:
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
大小不为
的拆分器和子拆分器的并行性较差,因此,在编写自己的并发集合时,最好编写自定义拆分器,而不要依赖默认拆分器实现。首先,您应该明确区分此处询问的拆分器
特征,这些特征取决于流的源;因为还有(并发的
,无序的
和标识
用于收集器
)
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, ...
据我所知,这些不是一个直接的1对1映射和来自Spliterator的映射,但它们仍然并没有被使用
目前(我搜索了jdk-8和jdk-9源代码),它们都没有被利用,但仍然被拆分器的一些实现报告(例如,Arrays
reportIMMUTABLE
和ConcurrentHashMap
reportsNONNULL
)
另一方面,这些标志可以在将来使用——如果您知道源不能包含null元素(NONNULL
),显然您可以跳过一些null检查或使用null定义一些状态。我想不出任何关于并发
或不可变
的例子,但可能有这样的例子
例如,在无序
和并发
收集器(!=拆分器
属性)的当前实现下,执行到当前映射
时,不会调用合并器
。例如:
Set.of("one", "two", "das", "dasda")
.stream()
.parallel()
.collect(Collectors.toConcurrentMap(Function.identity(), String::length));
不会调用组合器,因为不需要调用
可以针对您提到的3个特性中的任何一个进行类似的优化。例如,您可以读取其中的StreamOpFlag.ORDERED
更改了java 8与java 9中findFirst
的结果(可能是文档会回答您的问题;)我只找到了其余特性的答案:)据我所知,不可变
和非空
特性根本不使用(但可能会在未来的Java版本中使用)。@ZhekaKozlov感谢您提供的信息。有没有提到你读过的地方?我还怀疑,CONCURRENT
characteristic也没有被使用……嗯。。。这是特定于拆分器的。拆分器(集合)
,因为它们从迭代器创建拆分器;这不是一般的规则。通常集合可以更好地实现自己的拆分器。@Eugene是的,我在回答(最后一句)中注意到了这一点
Set.of("one", "two", "das", "dasda")
.stream()
.parallel()
.collect(Collectors.toConcurrentMap(Function.identity(), String::length));