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

Kyl*_*Bak 12 java optional java-8 java-stream

我正在进行服务电话并尝试处理响应.响应可能有一个列表.该列表可能为null.

此外,如果列表不为null或不为空,则需要对其进行过滤.在代码"entry"中,如果过滤不提供任何内容或响应列表为空或null,则引用可能为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) { ... }
Run Code Online (Sandbox Code Playgroud)

Ous*_* D. 13

如果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);
}
Run Code Online (Sandbox Code Playgroud)
  • 读取"如果responseEntries不为空responseEntries且不为空,则应用过滤器操作并查找第一个项目,否则为null".很可读.

另一方面,可选方法:

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
Run Code Online (Sandbox Code Playgroud)
  • 不必要地创建可以避免的对象,而不是真正意图将可选用作替代简单的"if"检查.


Nam*_*man 8

Stream.ofNullable (爪哇-9)

返回包含单个元素的顺序Stream (如果为非null), 否则返回空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
Run Code Online (Sandbox Code Playgroud)

更新的代码

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
Run Code Online (Sandbox Code Playgroud)

Optional.stream (爪哇-9)

返回包含该值的顺序Stream,否则 返回一个空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
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)


Rad*_*def 7

在Java 9中,您可以使用新方法Objects.requireNonNullElse(T,T):

Objects.requireNonNullElse(serviceResponse.getEntryList(),
                           Collections.emptyList())
Run Code Online (Sandbox Code Playgroud)

Apache Commons Collections实际上有一个方法ListUtils.emptyIfNull(List<T>),如果参数列表是,则返回一个空列表null.这甚至更好,但Objects.requireNonNullElse它是Java SE中最接近它的东西.

如果你只限于Java 8,那么我同意Aomine的回答,试图做一些像经历Optional的事情比if声明更糟糕.


Fed*_*ner 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) { ... }
Run Code Online (Sandbox Code Playgroud)

有时,传统的IMO更好.