如何使 Stream `max` 提前终止?

How do I make a Stream `max` early-terminate?

我正在针对 OpenJDK 16 写作并尝试充分利用流。我有一个案例需要 Stream.max 的混合,获取此比较器的元素:

    public static final Comparator<Solution> byMatched =
        Comparator.comparing(sol -> sol.pairs.size());

表示最大的pairs集合;但如果此 size() 达到已知上限,我也需要提前终止。我认为我可以使用内置插件获得的最接近的是

    public Solution best() {
        return StreamSupport.stream(this, true)
            .takeWhile(
                solution -> solution.pairs().size() < problem.animals().size()
            )
            .max(Solution.byMatched)
            .get();
    }

其中 this 实现 Spliterator<Solution>。这种方法是不正确的,因为虽然它确实提前终止,但看到的第一个达到最大问题大小的解决方案被 takeWhile 丢弃。

是否有应用 max 的内置流方法,但在给定谓词变为 true 时停止(并包括第一个值!)?

您可以使用有状态谓词 returns 在遇到第一个超过阈值的输入之前为真。

像这样:

class BoundedPredicate<T, V extends Comparable<V>> implements Predicate<T> {
    private V boundary; //the boundary
    private Function<T, V> extractor; //the value extractor to get what's needed for the comparison
    private boolean boundaryHit; //the flag that keeps track of whether the boundary was hit

    public BoundedPredicate(V boundary, Function<T, V> extractor) {
        super();
        this.boundary = boundary;
        this.extractor = extractor;
    }

    public boolean test(T value) {
        //boundary was hit last time so return false now
        if( boundaryHit) {
            return false;
        }
        
        //check boundary and if it was hit, update the flag
        if( boundary.compareTo(extractor.apply(value)) <= 0) {
            boundaryHit = true;
        }
        
        return true;
    }       
}

和用法:

return StreamSupport.stream(this, true)
        .takeWhile(
           new BoundedPredicate<Solution, Integer>(problem.animals().size(), solution -> solution.pairs().size() )                
        )
        .max(Solution.byMatched)
        .get();