【问题标题】:Java list null check before Stream and return as Optional在 Stream 之前进行 Java 列表空检查并作为可选返回
【发布时间】:2020-01-09 20:48:58
【问题描述】:

我正在从 API 获取对象列表

public Optional<List<Employee>> getEmployeeData (String deptId){

     List<Employee> employee = departmentClient.employeeData(deptId);

     //Based on some condition I am filtering employee list but before that I want to check  for null for list.

    return Optional.ofNullable(employee).orElse(Collections.emptyList())
            .stream()
            .filter(Objects::nonNull)
            .filter(e -> e.getType != null)
            .collect(Collectors.toList());

 }

但我认为方法返回类型是Optional&lt;&gt;,这会出错。如何在 Stream 之前检查 List 的 null 并以 Optional&lt;List&lt;..&gt;&gt; 的形式返回

【问题讨论】:

  • 在这种情况下,如果员工列表为空,则会抛出 NullPointerException 错误
  • 与问题无关,但出于好奇:为什么该方法设计为返回Optional&lt;List&lt;Employee&gt;&gt; 而不是List&lt;Employee&gt;,如果没有employees 匹配所需的条件,它可能为空? Optional 便于在以下情况下包装可能的 null 值 - 例如,找不到匹配项,但空集合可以更好地传达这一点并且代码更少。
  • Optional.ofNullable(employee) 甚至不应该是必需的,因为 employeeCollection 并且您在使用 stream 共享示例时不需要进一步的空检查。
  • 除非您有非常特殊的要求没有提出来,否则我建议departmentClient.employeeData() 永远不要返回null,如果没有要返回的员工数据则返回一个空列表。而且您的方法getEmployeeData() 不会返回Optional,而只会返回List&lt;Employee&gt;,如果没有要返回的数据,还会返回一个空列表。

标签: java java-8 java-stream optional


【解决方案1】:

你返回了List&lt;Employee&gt;,而你的方法签名是Optional&lt;List&lt;Employee&gt;&gt;

试试这个:

return employee != null ? Optional.of(employee.stream()
            .filter(Objects::nonNull)
            .filter(e -> e.getType != null)
            .collect(Collectors.toList())) : Optional.ofNullable(Collections.emptyList());

【讨论】:

    【解决方案2】:

    您的解决方案不起作用,因为Optional 的结果是List,您通过Stream 管道将其收集回List

    使用 Java 8,您可以将所有解决方案封装在 Optional 中,或者更好地利用 Collectors 的优势:

    Optional<List<Employee>> o = Optional
            .ofNullable(employees)                  // employees can be null, right?
            .orElse(Collections.emptyList())        // ... if so, then empty List
            .stream()                               // Stream<Employee>
            .filter(Objects::nonNull)               // Stream<Employee> filtered as non-nulls
            .filter(e -> e.getType() != null)       // Stream<Employee> with non-null field
            .collect(Collectors.collectingAndThen(  
                Collectors.toList(),                // Collected to List<Employee>
                Optional::of));                     // Collected to Optional<List<Employee>>
    

    Collectors::collectingAndThen(Collector&lt;T,A,R&gt; downstream, Function&lt;R,RR&gt; finisher) 方法的行为与通常的 Collector 一样,提供后续映射函数以获取收集的结果。在我们的例子中,我们只是将List 包装成Optional 以返回。

    • 收集器downstream 收集到List&lt;Employee&gt;
    • 函数finisherList&lt;Employee&gt; 映射到Optional&lt;List&lt;Employee&gt;&gt;

    使用 Java 9 及更高版本并使用 Optional::stream,开始时可能略有不同:

    Optional<List<Employee>> o = Optional
            .ofNullable(employees)                  // null-safe employees
            .stream()                               // Stream<List<Employees>>
            .flatMap(List::stream)                  // Stream<Employees>
            .filter(Objects::nonNull) 
            ......
    

    【讨论】:

      【解决方案3】:

      还有另一种选择:

      return Optional.ofNullable(employee)
              .map(list -> list.stream()
                      .filter(Objects::nonNull)
                      .filter(e -> e.getType() != null)
                      .collect(Collectors.toList()));
      

      .map(...) 中的 lambda 仅在 emploee 列表不为空时执行,否则返回空的 Optional

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-13
        • 1970-01-01
        • 2011-09-15
        • 2018-11-07
        • 1970-01-01
        • 2021-05-22
        • 1970-01-01
        • 2020-03-04
        相关资源
        最近更新 更多