如何';突破';Java约简方法的研究

如何';突破';Java约简方法的研究,java,java-stream,Java,Java Stream,我试图通过以下操作减少矩形类型的流: public static Optional<Rectangle> intersectAll(Stream<Rectangle> rectangles) { return rectangles .reduce((r1, r2) -> r1.intersection(r2)); public静态可选intersectAll(流矩形){ 返回矩形 .减少((r1,r2)->r1.交点(r2)); 方法inter

我试图通过以下操作减少矩形类型的流:

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

  return rectangles
      .reduce((r1, r2) -> r1.intersection(r2));
public静态可选intersectAll(流矩形){
返回矩形
.减少((r1,r2)->r1.交点(r2));
方法
intersection
接受一个类型为
Rectangle
的参数,返回类型为
Optional
,如果两个矩形相交,则返回
Optional.of(Rectangle)
,如果两个矩形不相交,则返回
Optional.empty()

我希望流减少到这样的程度:如果一次
r1.intersection(r2)
lambda函数返回一个空的可选值,那么方法
intersectAll
返回一个空的可选值,如果
r1.intersection(r2)
始终返回一个矩形,
intersectAll
的输出将是缩小的矩形


但是,正如您可能看到的,reduce不喜欢这样,因为交叉点方法不接受可选项,所以我想问,当reduce遇到一个空可选项时,是否有一种方法可以“中断”reduce,这样我就可以返回一个空可选项。

不可能中断reduce终端操作。但是,在某些情况下,您可以实现使用
过滤器、takewhile、findFirst
和类似的操作符实现目标。

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

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

标识是一个值,因此,
value op identity==value
-尝试为交叉点找到这样的标识通常不会。可能这就是您想要突破的原因。可能尝试将其视为一个提示,您想要走的路并不漂亮

至于组合器,你需要考虑如何组合结果——这可能不会太难。但我觉得这不是一条路要走

试着想象一下你要做什么。看前两行就知道它不合适。而且因为没有标识,所以没有意义(
空的相交矩形导致空的
,这不是标识)

R1相交R2相交R3相交R4
可选相交R3相交R4
可选交叉点R4
可选的

你可以用经典的方法来做吗?你可以更容易地打破循环。它也会更容易阅读。

你可以用一种有点脏的方法来做:
Optional optRect=矩形。reduce((r1,r2)->r1.equals(EMPTY)?EMPTY:r1.intersection(r2)。orElse(EMPTY));
然后
返回optRect.isPresent()和(opycRe..Value:OfType):optReCt;< /COD> >代码>空< /代码>表示一个特殊的<代码>矩形< /代码>。您可以考虑使用一个非纯谓词,该谓词累积到<代码>可选< /COD>外部,但此时,循环是一个更好的解决方案。
R1 intersect R2 intersect R3 intersect R4
   Optional<Ra> intersect R3 intersect R4
                Optional<Rb> intersect R4
                              Optional<Rc>