包含takeWhile()for Streams

问题描述 投票:1回答:2

我想知道是否有办法添加针对方法takeWhile()的条件测试的流的最后一个元素。我相信我想要实现类似于RxJava的takeUntil()方法。

我猜测没有直接的方法可以做到这一点(如果我弄错的话,请纠正我),但我想知道是否有一个正确的解决方法来实现这一点,我现在知道了。

我在Stackoverflow中搜索得很少甚至没有成功。如果你认为有线程可以解决我的问题,我当然希望看到它。

如果您查看以下代码的peek(),您将看到根据takeWhile()条件检查数字5,但它永远不会到达forEach():

IntStream.of(1, 3, 2, 5, 4, 6)
        .peek(foo -> System.out.println("Peek: " + foo))
        .takeWhile(n -> n < 5)
        .forEach(bar -> System.out.println("forEach: " + bar));

预期结果是针对takeWhile条件检查的最后一个元素到达forEach的System.out :: println。在这种情况下它是5。

谢谢大家!

java java-stream java-9
2个回答
4
投票

使用普通流API没有方便的方法。有可能在an ugly way(你需要调整这个实现,这只是一个正常的takeWhile“后向”Java 8)。

This guy编写了一个流扩展库,其中包含takeWhileInclusive

样品用法:

IntStreamEx.of(1, 3, 2, 5, 4, 6)
    .peek(foo -> System.out.println("Peek: " + foo))
    .takeWhileInclusive(n -> n < 5)
    .forEach(bar -> System.out.println("forEach: " + bar));

0
投票

我添加了一个可怕的方法,可能对你的(或任何)用例有点过分,但只是为了好玩。

public static void main(String[] args) {
    List<Integer> source = List.of(1, 3, 2, 5, 4, 6);
    Iterator<Integer> iterator = source.iterator();
    AtomicBoolean proceed = new AtomicBoolean(true);

    Stream
        .generate(() -> {
            if (!proceed.get() || !iterator.hasNext()) {
                return null;
            }
            int value = iterator.next();
            System.out.println("generate: " + value);
            proceed.set(value < 5);
            return value;
        })
        .takeWhile(Objects::nonNull)
        .forEach(bar -> System.out.println("forEach: " + bar));

}

输出将是:

generate: 1
forEach: 1
generate: 3
forEach: 3
generate: 2
forEach: 2
generate: 5
forEach: 5

关于这种方法最糟糕的事情可能是它给generate()一个责任(检查是否有更多)它不属于它。

© www.soinside.com 2019 - 2024. All rights reserved.