Stream.empty 的实际用途是什么?

Beg*_*ner 0 java java-8 java-stream

Stream#empty返回一个空的序列Stream。从本教程中,我了解到空流可能有助于在调用带有流参数的方法时避免空指针异常。但是,我想不出一个例子可以帮助我清楚地理解这个陈述。

Yas*_*jaj 6

假设您有一个包含某些逻辑StreamflatMap操作,您希望在Stream#empty满足某些条件时进行调用

listOfLists.stream().flatMap(list -> {
    // complex business logic, maybe even extracted in another method
    return xxx ? someList.stream() : Stream.empty();
});
Run Code Online (Sandbox Code Playgroud)

另一个例子是,就像Optional<T>在方法返回的情况下使返回更安全Stream<T>(假设是工厂方法)

public <T> Stream<T> makeFooStreamFrom(Object... parameters) {
    // decide on what to do based on the parameters
    return decisionMadeToReturnAnEmptyStream ? Stream.empty() : Stream.of(foo, bar);
} 
Run Code Online (Sandbox Code Playgroud)

至于方法接受Stream参数的例子,可以像这样给出一个很好的例子

public <T> void consumeStream(@NotNull Stream<T> stream) {
    // In this example, if this stream is null, you'll get a NullPointerException
    // However, if you make sure to invoke this method using Stream#empty
    // No need to worry about it
    // This is the security that Stream#empty will provide in this case
    stream.map(...).filter(...).forEach(...);
}
Run Code Online (Sandbox Code Playgroud)

@daniu 带来的第四个例子是当你有一个 nullable 时List。这在之前最相关,正如引入的那样Stream#ofNullable,顺便说一句,它Stream#empty也在内部使用

这是它的实现,也是第四个例子

public static<T> Stream<T> ofNullable(T t) {
    return t == null ? Stream.empty()
                     : StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}
Run Code Online (Sandbox Code Playgroud)

我们会认为上面的示例并不相关,因为它Stream无论如何都会返回 a ,但是底层实现使用了一个EMPTY_SPLITERATOR内部命名的常量,这将有助于提高性能,因为它是可重用的。

  • 请注意,“flatMap”明确允许函数返回“null”而不是“Stream.empty()”,以进行相同的处理。但人们可能更喜欢“Stream.empty()”作为编码风格的问题。此外,你不应该有“一个可为空的`List`”。请改用空列表。但是,当然,`Collections.emptyList().stream()`也必须返回一个值,并且在大多数实现中它将是`Stream.empty()`...... (2认同)