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
report
IMMUTABLE
ConcurrentHashMap
reports
NONNULL

另一方面,这些标志可以在将来使用——如果您知道源不能包含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));