【问题标题】:How to 'break out' of Java reduce method [duplicate]如何“突破”Java reduce方法[重复]
【发布时间】:2021-04-15 19:51:01
【问题描述】:

我正在尝试通过这样做来减少 Rectangle 类型的流:

public static Optional<Rectangle> intersectAll(Stream<Rectangle> rectangles) {

  return rectangles
      .reduce((r1, r2) -> r1.intersection(r2));

方法intersection 接受一个Rectangle 类型的参数,返回类型为Optional&lt;Rectangle&gt;,如果两个矩形相交则返回Optional.of(Rectangle),如果不相交则返回Optional.empty()

我希望减少流,这样如果有一次r1.intersection(r2) lambda 函数返回一个空的可选项,intersectAll 方法返回一个空的可选项,如果 r1.intersection(r2) 总是返回一个矩形,@ 的输出987654330@ 将是缩小的矩形。

但是,正如您可能看到的那样,reduce 不喜欢这样,因为交集方法不接受 Optional,所以我想问是否有办法在遇到 reduce 时“突破”一个空的可选项,所以我可以返回一个空的可选项。

【问题讨论】:

  • 你可以用一种有点脏的方式来做到这一点:Optional&lt;Rectangle&gt; optRect = rectangles.reduce((r1, r2) -&gt; r1.equals(EMPTY) ? EMPTY : r1.intersection(r2).orElse(EMPTY)); 然后return optRect.isPresent() &amp;&amp; optRect.get().equals(EMPTY) ? Optional.empty() : optRect; 其中EMPTY 表示一个特殊的Rectangle
  • 您可以考虑使用非纯谓词的 takeWhile,该谓词在外部累积到 Optional&lt;Rectangle&gt;,但此时循环是更好的解决方案。

标签: java java-stream


【解决方案1】:

不能中断减少终端操作。但是,在某些情况下,您可以使用filter, takewhile, findFirst 和类似的运算符来实现目标。

【讨论】:

    【解决方案2】:

    我确信可以找到解决方案,但我建议不要使用流。

    在我看来,矩形的交集并不适合减少操作。它没有身份。您还需要一个组合器(请参阅 Stream 类中 reduce 方法的其他方法签名)并适当地实现它。

    身份是一个值,因此value op identity == value - 通常尝试为交集找到这样的值,但您不会。可能这就是你想要突破的原因。也许试着把它看作一个暗示,你想走的路并不美丽。

    至于组合器,您需要考虑如何组合结果 - 这可能不会太难。我仍然觉得这不是要走的路。

    试着想象你想要做什么。前两行的外观表明它不适合。而且由于没有可以使用的身份,所以没有意义(Empty intersect Rectangle results in Empty,这不是身份)

    R1 intersect R2 intersect R3 intersect R4
       Optional<Ra> intersect R3 intersect R4
                    Optional<Rb> intersect R4
                                  Optional<Rc>
    

    你可以用经典的方式来做这件事吗?您可以更轻松地跳出循环。它也将更具可读性。

    【讨论】:

      猜你喜欢
      • 2016-07-08
      • 1970-01-01
      • 2020-07-08
      • 2023-01-12
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多