如何从可空对象中最好地创建Java 8流?

时间:2015-04-02 06:22:37

标签: java java-8 java-stream

在获取流之前进行空检查的最佳/惯用方法是什么?

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

6 个答案:

答案 0 :(得分:39)

我同意Stuart Marks list == null ? Stream.empty() : list.stream()是执行此操作的最佳方式(请参阅his answer),或至少是在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),它返回给定null参数的空流,否则返回一个以参数为唯一元素的流。如果参数是集合,我们可以flatMap将其转换为流。

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

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

答案 1 :(得分:12)

我能想到的最好的方法是使用Optional orElseGet方法。

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

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

答案 2 :(得分:12)

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

让我提出以下更平凡的技巧:

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

我想这三天的三元运算符有点多了,但我认为这是最简单,最有效的解决方案。

如果我是真的写这个(也就是说,对于一个真正的库,而不仅仅是Stack Overflow上的示例代码)我会添加通配符,以便流返回类型可以与List类型不同。哦,它可以是一个集合,因为那是定义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>的转换是安全的,但编译器不知道这一点。)

答案 3 :(得分:5)

apache commons-collections4:

CollectionUtils.emptyIfNull(list).stream()

答案 4 :(得分:1)

Java 8:

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

Java 9:

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

Apache Commons Collections 4:

import org.apache.commons.collections4.CollectionUtils;
CollectionUtils.emptyIfNull(collection)
    .stream()

答案 5 :(得分:0)

就个人而言,我认为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);
}