在Java 8中将Null安全集合为Stream

Gon*_*ndy 41 java collections null java-8 java-stream

我正在寻找可以使收集流,但是是安全的方法.如果collection为null,则返回空流.像这样:

Utils.nullSafeStream(collection).filter(...);
Run Code Online (Sandbox Code Playgroud)

我创建了自己的方法:

public static <T> Stream<T> nullSafeStream(Collection<T> collection) {
    if (collection == null) {
        return Stream.empty();
    }
    return collection.stream();
}
Run Code Online (Sandbox Code Playgroud)

但我很好奇,如果标准JDK中有这样的东西?

Era*_*ran 76

你可以使用Optional:

Optional.ofNullable(collection).orElse(Collections.emptySet()).stream()...
Run Code Online (Sandbox Code Playgroud)

我选择Collections.emptySet()任意作为默认值,如果collection是null.这将导致stream()方法调用生成为空,Stream如果collection为null.

示例:

Collection<Integer> collection = Arrays.asList (1,2,3);
System.out.println (Optional.ofNullable(collection).orElse(Collections.emptySet()).stream().count ());
collection = null;
System.out.println (Optional.ofNullable(collection).orElse(Collections.emptySet()).stream().count ());
Run Code Online (Sandbox Code Playgroud)

输出:

3
0
Run Code Online (Sandbox Code Playgroud)

或者,正如marstran建议的那样,您可以使用:

Optional.ofNullable(collection).map(Collection::stream).orElse(Stream.empty ())...
Run Code Online (Sandbox Code Playgroud)

  • `Optional.ofNullable(collection).map(Collection :: stream).orElse(Stream.empty());`是一个可能的等价解决方案,你不必选择`Collections.emptySet()`. (5认同)
  • 正如[@StuartMarks](http://stackoverflow.com/users/1441122/stuart-marks)所述_Use,Abstruse Use and Abuse_:[Rule#4](https://youtu.be/Ej0sss6cq14?t = 27m51s):_创建一个`Optional`通常是一个坏主意,其唯一目的是将方法链接到它以获得value_. (5认同)
  • @marstran Stuart Marks的观点是,一般来说,如果不使用可选项(在避免一些装箱和发件箱的事实之外),它将更具可读性.当然这仍然是一个指导方针. (4认同)

小智 35

您可以使用org.apache.commons.collections4.CollectionUtils :: emptyIfNull函数:

  org.apache.commons.collections4.CollectionUtils.emptyIfNull(list).stream().filter(...);
Run Code Online (Sandbox Code Playgroud)

  • 我其实喜欢这个解决方案,因为非常简单.但是,外部库是必需的,但在Maven和Gradle的世界中,这不是问题.我知道我要求JDK8,但显然没有这么简单. (2认同)
  • 不能使用“orElse”或“orElseThrow”,但“Optional.ofNullable()”提供这两种方法。 (2认同)

Did*_*r L 8

您的collectionAsStream()方法可以简化为比使用时更简单的版本Optional:

public static <T> Stream<T> collectionAsStream(Collection<T> collection) {
    return collection == null ? Stream.empty() : collection.stream();
}
Run Code Online (Sandbox Code Playgroud)

请注意,在大多数情况下,在构建流管道之前测试nullness可能更好:

if (collection != null) {
    collection.stream().filter(...)
} // else do nothing
Run Code Online (Sandbox Code Playgroud)

你想要什么似乎只在你需要返回流(包括用于平面映射),或者可能与另一个连接时才有用.


小智 6

不确定是否有帮助,但是由于Java 9,您可以编写:

Stream.ofNullable(nullableCollection)
      .flatMap(Collection::stream)
Run Code Online (Sandbox Code Playgroud)


g-t*_*g-t 5

您可以使用类似这样的内容:

public static void main(String [] args) {
    List<String> someList = new ArrayList<>();
    asStream(someList).forEach(System.out::println);
}

public static <T> Stream<T> asStream(final Collection<T> collection) {
    return Optional.ofNullable(collection)
            .map(Collection::stream)
            .orElseGet(Stream::empty);
}
Run Code Online (Sandbox Code Playgroud)


all*_*tej 5

如果org.apache.commons.collections4无法下载该库,则可以编写自己的包装器/便捷方法。

public static <T> Stream<T> asStream(final Collection<T> collection) {
    return collection == null ? ( Stream<T> ) Collections.emptyList().stream() 
                              : collection.stream();
}
Run Code Online (Sandbox Code Playgroud)

或用 Optional.ofNullable

public static <T> Stream<T> asStream(final Collection<T> collection) {
    return Optional.ofNullable(collection)
            .orElse( Collections.emptySet()).stream();
}
Run Code Online (Sandbox Code Playgroud)