java8 filter判断是否为空,如何检查Java 8 Stream是否为空?

博客探讨了如何在不物化流的情况下,检查Java Stream是否为空,若为空则抛出异常。给出了一个解决方案,实现了一个`nonEmptyStream`方法,通过`Spliterator`来判断流是否为空,还给出了示例代码,同时提到该方案在并行执行方面存在的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

How can I check if a Stream is empty and throw an exception if it's not, as a non-terminal operation?

Basically, I'm looking for something equivalent to the code below, but without materializing the stream in-between. In particular, the check should not occur before the stream is actually consumed by a terminal operation.

public Stream getFilteredThings() {

Stream stream = getThings().stream()

.filter(Thing::isFoo)

.filter(Thing::isBar);

return nonEmptyStream(stream, () -> {

throw new RuntimeException("No foo bar things available")

});

}

private static Stream nonEmptyStream(Stream stream, Supplier defaultValue) {

List list = stream.collect(Collectors.toList());

if (list.isEmpty()) list.add(defaultValue.get());

return list.stream();

}

解决方案

If you can live with limited parallel capablilities, the following solution will work:

private static Stream nonEmptyStream(

Stream stream, Supplier e) {

Spliterator it=stream.spliterator();

return StreamSupport.stream(new Spliterator() {

boolean seen;

public boolean tryAdvance(Consumer super T> action) {

boolean r=it.tryAdvance(action);

if(!seen && !r) throw e.get();

seen=true;

return r;

}

public Spliterator trySplit() { return null; }

public long estimateSize() { return it.estimateSize(); }

public int characteristics() { return it.characteristics(); }

}, false);

}

Here is some example code using it:

List l=Arrays.asList("hello", "world");

nonEmptyStream(l.stream(), ()->new RuntimeException("No strings available"))

.forEach(System.out::println);

nonEmptyStream(l.stream().filter(s->s.startsWith("x")),

()->new RuntimeException("No strings available"))

.forEach(System.out::println);

The problem with (efficient) parallel execution is that supporting splitting of the Spliterator requires a thread-safe way to notice whether either of the fragments has seen any value in a thread-safe manner. Then the last of the fragments executing tryAdvance has to realize that it is the last one (and it also couldn’t advance) to throw the appropriate exception. So I didn’t add support for splitting here.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值