【问题标题】:java: reduce vs anyMatch vs containsjava:reduce vs anyMatch vs contains
【发布时间】:2019-04-05 19:19:45
【问题描述】:
 List<Boolean> results = new ArrayList<>();
 results.add(true);
 results.add(true);
 results.add(true);
 results.add(false);

 if (results.contains(false)) {
     System.out.println(false);
 } else {
     System.out.println(true);
 }

 System.out.println(results.stream().reduce((a, b) -> a && b).get());
 //System.out.println(!results.stream().anyMatch(a -> a == false));
 System.out.println(!results.stream().anyMatch(a -> !a));

输出:


假的

仅供参考,结果是地图+收集操作的结果

List<Job> jobs;
List<Boolean> results = job.stream().map(j -> j.ready()).collect(Collector.toList())

如果我选择 reduce 或 anyMatch,我就不必收集 map 操作的结果。

从一个布尔值列表的结果中,如果至少有一个 false,我只想返回 false。

我可以通过 reduce 或 anyMatch 做到这一点。我有点不喜欢 reduce 中的 Optional,我有点不喜欢我必须否定 anyMatch

使用这两种方法有什么优缺点吗?

【问题讨论】:

    标签: java java-8 java-stream


    【解决方案1】:

    您将布尔值收集到列表中的唯一原因似乎是您可以检查其中一些是否为false

    如果我选择 reduce 或 anyMatch,我不必从 map 操作中收集结果 [...] 我只想在至少有一个 false 时返回 false。

    如果是这种情况,那么您绝对应该考虑直接基于流的方法:

    return jobs.stream().allMatch(Job::ready);
    

    【讨论】:

      【解决方案2】:

      你问利弊。 Contains 是最快最简单的。 Reduce 是这里最麻烦/最复杂的。但是你的任务很简单,那么它真的重要吗?选择使用哪种方法的更好的关键可能是:“哪个更易读、易理解和可维护?”这种干净的代码方法在实际软件开发中通常比在运行时或源代码中寻找微秒数更重要。但话又说回来,contains 是这里最好的。

      System.out.println(!results.contains(false));
      

      那么您的anyMatch(a -&gt; !a) 实际上与contains 相同,对于这个具体任务,我肯定更喜欢它而不是reduce。但同样,真正的差异非常小,我更关心该软件未来维护者的可读性和可理解性。

      【讨论】:

      • 感谢您的意见。我的编辑是否会改变您对答案的看法?我的原始代码是“包含”方法,但我收到了我应该做 map-reduce 或 map-anymatch 的 cmets
      • 流是处理任何东西最慢的方法,除非你有 1000 个元素并且使用并行流;引擎盖下发生了很多事情。此外,contains() 简短、易于编码和阅读,而且速度最快。
      • @Bohemian 是的,因此我选择了 contains,但我是团队中的新人,所以不想拒绝他们的建议。然后可能会选择 anyMatch
      • @Bohemian 如果流是处理事物的最慢方式,为什么建议使用流?
      • @Bohemian 我不同意“流是处理任何东西最慢的方式”。由于与集合的交互方式不同,在某些情况下 Stream 可以比传统循环执行得更快。但是,对于集合本身提供真正的执行方式的操作,应该始终首选这种方式,因为它不仅可能更有效,而且通常也更简单。 Stream 过度使用的最糟糕的例子是那些通过SetMap 流式传输以找到匹配键,而这两个源都提供了优于线性查找操作。
      【解决方案3】:
       System.out.println(results.stream().reduce((a, b) -> a && b).get());
      

      这将始终返回 false,因为列表 (results) 至少有 1 个false

      && 将始终检查两个值是否为真以将其作为true 传递。

       System.out.println(!results.stream().anyMatch(a -> !a));
      

      Stream anyMatch(Predicate predicate) 返回此流的任何元素(results)是否匹配提供的谓词(a -&gt; !a)。正如您正在做的那样!results,所以在初始 true 之后,结果最终会是错误的。

      【讨论】:

      • 我不知道你在anyMatch上是否正确,如果谓词匹配(true),即元素为假,它​​将返回false
      猜你喜欢
      • 1970-01-01
      • 2011-02-05
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 1970-01-01
      • 2014-08-31
      相关资源
      最近更新 更多