如何使用Stream API返回null?

时间:2018-07-27 13:36:57

标签: java lambda java-8 java-stream optional

因此,我有一个ArrayList自动生成的字符串。我想找到包含某些字符的第一个元素,否则,如果没有一个元素与此过滤器匹配,则应用另一个过滤器。换句话说,我想返回null对象。

所以我写了这个lambda表达式:

str.stream()
   .filter(s -> s.contains("q"))
   .findFirst()
   .orElseGet(() -> str.stream()
                       .filter(s -> s.contains("w"))
                       .findFirst()
                       .orElseGet(null))

但是,如果没有一个元素与这两个过滤器匹配,则将出现NullPointerException。如何获得类似return null的内容?

4 个答案:

答案 0 :(得分:6)

除非我缺少明显的内容,否则只需.orElse(null),而不是最后一个orElseGetorElseGet接受Supplier,而您传递了一个null,并在空引用上调用get(),那么...

答案 1 :(得分:4)

问题是Optional::orElseGet(null),它接受​​Supplier<T>并抛出NullPointerException

使用Optional::orElse(null),它接受​​T,在您的情况下为String

以下代码有效:

List<String> str = Arrays.asList("a", "b", "c");
String output = str.stream()
                   .filter(s -> s.contains("q"))
                   .findFirst()
                   .orElseGet(() -> str.stream()
                                       .filter(s -> s.contains("w"))
                                       .findFirst()
                                       .orElse(null));                 // <-- HERE

System.out.println(output);    // Prints null

或者,使用Optional::orElseGet(Supplier<? extends T> other)返回nullSupplier本身不能为null

.orElseGet(() -> null));

答案 2 :(得分:2)

orElseGet期望Supplier,您需要传递一个值,orElse就是这种情况。

在这里我不会使用Stream API,一次迭代就可以解决问题:

String wString = null;
for (String s : str) {
    if (s.contains("q")) return s;
    if (s.contains("w") && wString == null) wString = s;
}
return wString;

答案 3 :(得分:1)

另一种更简单的方法:您可以过滤包含qw的字符串,然后排序以首先移动包含q的字符串,首先查找,如果可选为空,则返回null :

str.stream()
    .filter(s -> s.contains("q") || s.contains("w"))
    .sorted((s1, s2) -> s1.contains("q") ? -1 : 1 )
    .findFirst()
    .orElse(null);

.sorted((s1, s2) -> s1.contains("q") ? -1 : 1 )将首先移动包含"q"的字符串。由于仅对包含qw的值进行了流过滤,因此返回null只会发生任何保留元素的情况。