如何“打破”Java的reduce方法

3
我正在尝试通过以下方式来减少类型为矩形的流:
public static Optional<Rectangle> intersectAll(Stream<Rectangle> rectangles) {

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

方法intersection接受一个类型为Rectangle的参数,返回类型为Optional<Rectangle>。如果两个矩形相交,则返回Optional.of(Rectangle),否则返回Optional.empty()
我希望将流减少至若一次r1.intersection(r2) Lambda函数返回空可选项,则intersectAll方法返回空可选项。如果r1.intersection(r2)始终返回矩形,则intersectAll输出结果将仅为减少后的矩形。
然而,由于可以看到intersection方法不接受可选参数,因此reduce无法正常工作。所以我想问是否有一种方法可以在遇到空可选项时“跳出”reduce循环,以便我可以返回空可选项。

1
你可以用一种有点“不规范”的方式来实现这个:Optional<Rectangle> optRect = rectangles.reduce((r1, r2) -> r1.equals(EMPTY) ? EMPTY : r1.intersection(r2).orElse(EMPTY)); 然后 return optRect.isPresent() && optRect.get().equals(EMPTY) ? Optional.empty() : optRect; 其中 EMPTY 表示一个特殊的 Rectangle - Aniket Sahrawat
1
你可以考虑使用一个非纯断言的takeWhile函数,将结果累加到一个Optional<Rectangle>中,但是在这种情况下,使用循环更为合适。 - njzk2
2个回答

0

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


0

我确定可以找到一个解决方案,但是我建议不要使用流来实现。

在我看来,矩形的交集并不适合使用reduce操作。它没有一个恒等元素。你还需要一个组合器(参见Stream类中reduce方法的其他方法签名)并适当地实现它。

恒等元素是一个数值,使得value op identity == value——试着去找一个这样的交集恒等元素,你会发现没有。也许这就是你想要放弃的原因。也许试着将其视为一个提示,你想要从事的路径并不美丽。

至于组合器,你需要思考如何将结果组合起来,这可能不太难。但我仍然感觉这不是正确的方法。

试着想象一下你想做的事情。首先两行代码就暴露出它无法适用。并且由于没有可用的恒等元素,所以它没有意义(空的交集矩形结果为空,这不是恒等元素)。

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

你觉得按照传统的方式做可以吗?这样你可以更容易地跳出循环,而且代码可读性也会更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接