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

w3nuxt5m  于 2023-02-07  发布在  Java
关注(0)|答案(6)|浏览(144)

我正在进行服务调用,并试图处理响应。响应可能有一个列表的东西。该列表可能是空的。
此外,如果列表不为空,那么它需要被过滤。在代码中,如果过滤没有结果或者响应列表为空,那么“entry”引用可能为空。
目前,当我试图在一个空响应列表上使用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) { ... }
llycmphe

llycmphe1#

Stream.ofNullable(Java-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

更新代码

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)

返回仅包含该值的顺序 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

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
}
o2gm4chl

o2gm4chl2#

如果list不为null或不为空,则需要对其进行过滤。
这里不需要Optional,因为它不打算替换简单的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
  • 不必要地创建了可以避免的对象,并且optional并不是要替代简单的“if”检查。
lrl1mhuk

lrl1mhuk3#

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

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

Apache Commons Collections实际上有一个方法ListUtils.emptyIfNull(List<T>),如果参数列表是null,它会返回一个空列表,这更好,但是Objects.requireNonNullElse是Java SE中最接近它的东西。
如果您只限于Java8,那么我同意Aomine的回答,即尝试执行Optional之类的操作比if语句更糟糕。

xfyts7mz

xfyts7mz4#

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

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) { ... }

有时候,传统的更好海事组织。

cunj1qz1

cunj1qz15#

另一种选择是使用Optional单子:

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

if (!entry.isPresent()) {
    …
}

如果您的目标是构建(并返回)一个值,而不是执行副作用,您甚至可以使用orElseGet来代替if语句。

ql3eal8s

ql3eal8s6#

我是新的可选,我可能是错误的。逻辑可以写如下,如果你想有逻辑只包括可选的。

ServiceResponse serviceResponse = service.getServiceResponse();
ResponseEntry entry = 

Optional.of(CollectionUtils.isNotEmpty(serviceResponse.getEntryList()))
        .filter(BooleanUtils::isTrue)
        .stream()
        .filter(e -> "expectedValue".equals(e.getValue()))
        .findFirst()
        .orElse(null);

相关问题