如何最好地从可为 null 的对象创建 Java 8 流?

How to best create a Java 8 stream from a nullable object?

在获取流之前进行空值检查的 best/idiomatic 方法是什么?

我的方法正在接收可能为空的 List。所以我不能只对传入的值调用 .stream() 。如果值为空,是否有一些静态助手会给我一个空流?

我能想到的最好的办法是使用 OptionalorElseGet 方法。

return Optional.ofNullable(userList)
                .orElseGet(Collections::emptyList)
                .stream()
                .map(user -> user.getName())
                .collect(toList());

已更新 @Misha 建议使用 Collections::emptyList 而不是 ArrayList::new

我同意 Stuart Marks that list == null ? Stream.empty() : list.stream() is the right way to do this (see ),或者至少是在 Java 9 之前执行此操作的正确方法(请参阅下面的编辑),但我将保留此答案以演示使用可选 API.

<T> Stream<T> getStream(List<T> list) {
    return Optional.ofNullable(list).map(List::stream).orElseGet(Stream::empty);
}

编辑: Java 9 添加了静态工厂方法Stream.<T>ofNullable(T), which returns the empty stream given a null argument, otherwise a stream with the argument as its only element. If the argument is a collection, we can then flatMap 将其转换为流。

<T> Stream<T> fromNullableCollection(Collection<? extends T> collection) {
    return Stream.ofNullable(collection).flatMap(Collection::stream);
}

这不会像 Stuart Marks 所讨论的那样滥用 Optional API,并且与三元运算符解决方案相比,没有空指针异常的机会(就像你没有注意和搞砸了操作数的顺序)。由于 flatMap 的签名,它还可以使用上限通配符而不需要 SuppressWarnings("unchecked"),因此您可以从 [=19= 的任何子类型的元素集合中获得 Stream<T> ].

在其他答案中,Optional 实例严格在同一语句中创建和使用。 Optional class 主要用于 communicating with the caller 关于 return 值是否存在,如果存在则与实际值融合。在单一方法中完全使用它似乎是不必要的。

让我提出以下更平淡的技术:

static <T> Stream<T> nullableListToStream(List<T> list) {
    return list == null ? Stream.empty() : list.stream();
}

我想现在三元运算符有点 déclassé,但我认为这是最简单和最有效的解决方案。

如果我真的要写这篇文章(也就是说,对于一个真正的库,而不仅仅是 Stack Overflow 上的示例代码),我会放入通配符,以便流 return 类型可以不同于列表类型。哦,它可以是一个集合,因为那是定义 stream() 方法的地方:

@SuppressWarnings("unchecked")
static <T> Stream<T> nullableCollectionToStream(Collection<? extends T> coll) {
    return coll == null ? Stream.empty() : (Stream<T>)coll.stream();
}

(警告抑制是必要的,因为从 Stream<? extends T>Stream<T> 的转换是安全的,但编译器不知道。)

apache commons-collections4:

CollectionUtils.emptyIfNull(list).stream()

我个人认为不推荐使用 null 并尽可能使用 Optional,尽管(微小的)性能开销。因此,我将 Stuart Marks 的接口与基于 gdejohn 的实现结合使用,即

@SuppressWarnings("unchecked")
static <T> Stream<T> nullableCollectionToStream(Collection<? extends T> coll)
{
    return (Stream<T>) Optional.ofNullable(coll)
                           .map(Collection::stream)
                           .orElseGet(Stream::empty);
}

Java 8:

Optional.ofNullable(list)
   .orElseGet(Collections::emptyList)
   .stream()

Java 9:

Stream.ofNullable(collection)
    .flatMap(Collection::stream)

Apache Commons 集合 4:

import org.apache.commons.collections4.CollectionUtils;

CollectionUtils.emptyIfNull(collection)
    .stream()