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

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

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.

Java 8判断 `Map` 是否,虽然语言本身没有新增专门用于“判断”的语法,但我们可以结合 Java 8 的 `Optional` 和 Stream 操作来更安全、更函数式地处理可能为 `null` 的 `Map`。 不过,最核心的判断方式仍然是调用 `isEmpty()` 方法,再结合 `null` 检查。以下是几种常见的做法: --- ### ✅ 推荐方法一:传统方式(安全且简洁) ```java Map<String, Integer> map = getMap(); // 可能为 null 或 empty if (map == null || map.isEmpty()) { System.out.println("Map 是的"); } else { System.out.println("Map 不为,大小为: " + map.size()); } ``` - `map == null`:检查是否为 `null` - `map.isEmpty()`:检查是否没有元素(即 `size() == 0`) > ⚠️ 注意:如果 `map` 为 `null`,直接调用 `isEmpty()` 会抛出 `NullPointerException`,所以必须先判 `null`。 --- ### ✅ 方法二:使用 Java 8 `Optional` 安全访问 当你想以函数式风格处理可能为 `null` 的 `Map` 时,可以使用 `Optional.ofNullable()`: ```java import java.util.*; Map<String, Integer> map = getMap(); Optional.ofNullable(map) .map(m -> m.isEmpty() ? "empty" : "not empty") .orElse("null or empty"); ``` 或者更实用一点:打印每种状态 ```java String result = Optional.ofNullable(map) .map(m -> { if (m.isEmpty()) { return "Map is null or empty"; } else { return "Map has " + m.size() + " entries"; } }) .orElse("Map is null"); System.out.println(result); ``` 你也可以用它来触发某些操作: ```java Optional.ofNullable(map) .filter(m -> !m.isEmpty()) // 过滤掉 null 或 empty .ifPresent(m -> m.forEach((k, v) -> System.out.println(k + " -> " + v))); ``` > 🔍 解释: > - `Optional.ofNullable(map)`:包装可能为 `null` 的对象。 > - `.filter(...)`:只有当 map 非时才继续。 > - `.ifPresent(...)`:安全执行遍历,避免指针。 --- ### ✅ 方法三:封装成工具方法(推荐复用) ```java public static <K, V> boolean isEmpty(Map<K, V> map) { return map == null || map.isEmpty(); } public static <K, V> boolean isNotEmpty(Map<K, V> map) { return map != null && !map.isEmpty(); } ``` 使用示例: ```java if (isNotEmpty(map)) { map.forEach((k, v) -> System.out.println(k + " -> " + v)); } ``` --- ### ❌ 错误写法示例(会导致 NPE) ```java // 危险!如果 map 为 null,会抛出 NullPointerException if (map.isEmpty()) { ... } // ❌ 不安全 ``` --- ### 总结对比 | 方法 | 是否推荐 | 说明 | |------|----------|------| | `map == null || map.isEmpty()` | ✅ 强烈推荐 | 简单高效,适用于大多数场景 | | `Optional.ofNullable(...)` | ✅ 推荐 | 函数式编程风格,适合链式调用 | | 封装工具方法 | ✅ 推荐 | 提高代码可读性和复用性 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值