当前位置: 首页 > 知识库问答 >
问题:

哪些流操作使用“CONCURRENT”、“IMMUTABLE”和“NONNULL”Spliterator特性?

上官华池
2023-03-14

哪些流操作使用并发不可变非空拆分器特性?它们在这些操作中如何发挥作用?

我不是问这些标志是什么,这在文档中很容易找到。我在问哪些操作使用它们以及如何使用它们。

共有3个答案

赵炯
2023-03-14

人们说IMMUTABLE没有被使用,但事实证明,Stream#iterate报告IMMUTABLE

jshell> Stream.iterate(0, i -> i + 1).spliterator().characteristics()
$1 ==> 1040

1040是< code >不可变|有序的,但它看起来像是任何操作都放弃< code >不可变(用< code>map、< code>filter、< code>flatMap、< code>limit、< code>skip测试;在Java 16上测试)< br > < code > int stream # iterate 、< code>LongStream#iterate和< code > DoubleStream # iterate 也报告< code>NONNULL,但在下一个操作中也会将其删除。

雷曜灿
2023-03-14

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

但是,当您编写自己的集合时,< code>CONCURRENT特性可能会影响并行流的行为。如果从集合中创建< code >拆分器,并且不报告< code >并发特征,则拆分器将另外具有< code >大小和< code >子大小特征:

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

但是,如果您报告并发特征,则拆分器不再 SIZE

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的拆分器并行性很差,因此当您编写自己的并发集合时,最好编写自定义拆分器而不是依赖于默认的拆分器实现。

马阳晖
2023-03-14

首先,您应该明确区分您在这里询问的有关拆分器特征,这些特征取决于流的源;因为还有(例如,对于收集器并发无序IDENTITY_FINISH)。

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实现报告(数组报告IMMUTABLEProcurrentHashMap报告NONNULL例如)。

另一方面,这些标志可以在将来使用——如果您知道一个源不能包含空元素(< code>NONNULL),显然您可以跳过一些空检查或者用空定义一些状态。我想不出任何< code>CONCURRENT或< code>IMMUTABLE的例子,但可能有这样的例子。

例如,在无序并发收集器(!=拆分器属性)的当前实现下,当执行到concurrentmap,不会调用组合器。例如:

Set.of("one", "two", "das", "dasda")
            .stream()
            .parallel()
            .collect(Collectors.toConcurrentMap(Function.identity(), String::length));

不会调用合并器 - 因为没有必要。

可以针对您提到的3个特征中的任何一个进行这样的优化。例如,您可以在StreamOpFlag.ORDERED中更改java 8与java 9中的findFirst的结果。

 类似资料:
  • 问题内容: 我有以下代码: 但我不明白为什么会返回3而不是2。 问题答案: 您还需要重写class中的方法。例如: 当两个对象相等时,它们的方法必须返回相同的值。 接口的API文档没有提及这一点,但是众所周知,如果您覆盖,则还应该覆盖。API文档提到了这一点: 请注意,通常有必要在重写此方法时重写该方法,以维护该方法的常规协定,该协定规定相等的对象必须具有相等的哈希码。 显然,确实使用了对象的哈希

  • null > (Docs) +javax包因此看起来是未来的证明 -是JEE的一部分,而不是JSE的一部分。在JSE中,需要导入其他库。 -静态分析工具不支持(仅运行时验证) (docs) -外部库,而不是包 -自findbugs版本3.x以来已不推荐使用 +用于静态分析(由findbugs和Sonar使用) (docs) +用于静态分析(在findbugs中) -JSR-305在fb邮件列表中显

  • 本文向大家介绍会引起Reflow和Repaint的操作有哪些?相关面试题,主要包含被问及会引起Reflow和Repaint的操作有哪些?时的应答技巧和注意事项,需要的朋友参考一下 https://github.com/encountermm/learning-notes/blob/master/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%

  • 我正在使用Intellij13.1.5和Java8 SDK,我已经设置了IntelliJ内置的nullness检查器,以便使用作为我选择的注释。 现在,当我写一个像这样的简单类时 我的下一个猜测是,多个库使用相同的注释名称,可能会出现名称冲突。但不幸的是,警告没有指定包的确切类名。如果是这种情况,一定有某种设置启用隐式注释。 如何在不删除注释的情况下删除此警告?

  • 问题内容: Java中的哪些操作被视为原子操作? 问题答案: 除long和double以外的所有基本类型分配 所有参考文献的分配 易变变量的所有分配 java.concurrent.Atomic 类的所有操作 也许还有更多。看看jls。 如评论中所述,原子性并不意味着可见性。因此int,即使保证另一个线程看不到部分写入的内容,也可能永远看不到新值。

  • 本文向大家介绍HTTP2.0 有哪些特性?相关面试题,主要包含被问及HTTP2.0 有哪些特性?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: http2.0的特性如下: 1、内容安全,应为http2.0是基于https的,天然具有安全特性,通过http2.0的特性可以避免单纯使用https的性能下降 2、二进制格式,http1.X的解析是基于文本的,http2.0将所有的传输信息分割为更