有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何使用Java8处理可空列表?

我正在打一个服务电话并试图处理回复。 响应可能有一个列表。该列表可能为空

此外,如果列表不为null或不为空,则 它需要过滤。 在代码中,如果过滤不提供任何内容或响应列表为空或null,则“entry”引用可能为null

当前,当我尝试在空响应列表上使用stream()时,我得到了NPE。 我如何处理这种情况

@Getter
public class ServiceResponse {  
    List<ResponseEntry> entryList;
}

@Getter
public class ResponseEntry {
    String value;
}


ServiceResponse serviceResponse = service.getServiceResponse();
ResponseEntry entry = serviceResponse.getEntryList()
    .stream()
    .filter(e -> "expectedValue".equals(e.getValue()))
    .findFirst()
    .orElse(null);

if (entry == null) { ... }


共 (5) 个答案

  1. # 1 楼答案

    if list not null or not empty, then it needs to be filtered.

    这里不需要可选的,因为它不打算取代简单的if检查

    ResponseEntry entry = null;
    List<ResponseEntry> responseEntries = serviceResponse.getEntryList();
    if(responseEntries != null && !responseEntries.isEmpty()){
        entry = responseEntries.stream()
                    .filter(e -> "expectedValue".equals(e.getValue()))
                    .findFirst()
                    .orElse(null);
    }
    
    • 读取“如果responseEntries不为空且responseEntries不为空,则应用筛选操作并查找第一项,否则为空”。非常可读

    另一方面,可选方法:

    ResponseEntry entry = Optional.ofNullable(serviceResponse.getEntryList())
                                  .orElseGet(() -> Collections.emptyList())
                                  .stream()
                                  .filter(e -> "expectedValue".equals(e.getValue()))
                                  .findFirst();
    
    if(!entry.isPresent()){ ... } // or entry.ifPresent(e -> ...) depending on the logic you're performing inside the block
    
    • 不必要地创建可以避免的对象,而不是真正的可选对象,以替代简单的“如果”检查
  2. # 2 楼答案

    在Java 9中,可以使用新方法^{}

    Objects.requireNonNullElse(serviceResponse.getEntryList(),
                               Collections.emptyList())
    

    Apache Commons Collections实际上有一个方法^{},如果参数列表是^{,它将返回一个空列表。这甚至更好,但在JavaSE中Objects.requireNonNullElse是最接近它的东西

    如果您仅限于Java 8,那么我同意Aomine的回答,即尝试执行Optional之类的操作比if语句更糟糕

  3. # 3 楼答案

    ^{}(Java-9)

    Returns a sequential Stream containing a single element, if non-null, otherwise returns an empty Stream.

    当前代码

    ResponseEntry entry = serviceResponse.getEntryList() // List<ResponseEntry>
            .stream() // NPE here   // Stream<ResponseEntry>
            .filter(e -> "expectedValue".equals(e.getValue())) // filter
            .findFirst() // Optional<ResponseEntry>
            .orElse(null); // or else null
    

    更新代码

    ResponseEntry entry = Stream.ofNullable(serviceResponse.getEntryList()) // Stream<List<ResponseEntry>>
            .flatMap(List::stream) // Stream<ResponseEntry>
            .filter(e -> "expectedValue".equals(e.getValue())) // filter here
            .findFirst() // Optional<ResponseEntry>
            .orElse(null); // or else null
    

    ^{}(Java-9)

    returns a sequential Stream containing only that value, otherwise returns an empty Stream.

    ResponseEntry entry = Optional.ofNullable(serviceResponse.getEntryList())
            .stream() // Stream<List<ResponseEntry>>
            .flatMap(List::stream) // Stream<ResponseEntry>
            .filter(e -> "expectedValue".equals(e.getValue())) // filter here
            .findFirst() // Optional<ResponseEntry>
            .orElse(null); // or else null
    

    ^{}(Java-11)

    If a value is not present, returns true, otherwise false

    Optional<ResponseEntry> entry = Optional.ofNullable(serviceResponse.getEntryList()) // Optional<List<ResponseEntry>>
            .orElseGet(Collections::emptyList) // or else empty List
            .stream() // Stream<ResponseEntry>
            .filter(e -> "expectedValue".equals(e.getValue())) // filter
            .findFirst(); // Optional<ResponseEntry>
    
    if (entry.isEmpty()) { // !entry.isPresent in java-8
       // Do your work here
    }
    
  4. # 4 楼答案

    另一种选择是使用Optionalmonad

    Optional<ResponseEntry> entry = Optional.ofNullable(serviceResponse.getEntryList()).flatMap(list ->
        list.stream().filter(e -> "expectedValue".equals(e.getValue())).findFirst()
    );
    
    if (!entry.isPresent()) {
        …
    }
    

    如果您的目标是构建(并返回)一个值,而不是执行副作用,那么甚至可以使用^{}而不是if语句

  5. # 5 楼答案

    您可以简单地使用三元运算符:

    ServiceResponse serviceResponse = service.getServiceResponse();
    List<ResponseEntry> list = serviceResponse.getEntryList();
    
    ResponseEntry entry = (list == null ? Collections.emptyList() : list)
        .stream()
        .filter(e -> "expectedValue".equals(e.getValue()))
        .findFirst()
        .orElse(null);
    
    if (entry == null) { ... }
    

    有时候,传统的更好