我想知道是否有办法添加针对方法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。
谢谢大家!
使用普通流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));
我添加了一个可怕的方法,可能对你的(或任何)用例有点过分,但只是为了好玩。
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()
一个责任(检查是否有更多)它不属于它。