如何使用java 8处理可为空的列表?

2022-09-03 08:51:24

我正在进行服务调用并尝试处理响应。响应可能包含某些内容的列表。该列表可能为空。

此外,如果 list 不为 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) { ... }


答案 1

Stream.ofNullable (Java-9)

返回包含单个元素的顺序流(如果非 null),否则返回空流

当前代码

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

Optional.stream (Java-9)

返回仅包含该值的顺序否则返回空流

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

Optional.isEmpty(Java-11)

如果值不存在,则返回 true否则返回 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
}

答案 2

如果 list 不为 null 或不为空,则需要对其进行筛选。

这里不需要可选,因为它不是用来取代简单的检查。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);
}
  • 读取“如果不是 null 且不为空,则应用筛选器操作并查找第一项,否则为 null”。非常可读。responseEntriesresponseEntries

另一方面,可选方法:

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
  • 不必要地创建可以避免的对象,而不是真正意义上的可选对象,以替代简单的“if”检查。

推荐