使用Java 8功能在列表中搜索非空列表

use*_*286 9 java optional java-8 java-stream

我有一个代码片段,我希望使用像lambdas/streams等Java 8功能更简洁可读.

基本上,有一个项目列表,每个项目都有一个错误列表.如果至少有一个项目至少有一个错误,则需要返回"失败".如果没有任何错误的项目,请返回"成功".

Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());

if (optionalItemList.isPresent())
    for (Item item : optionalItemList.get()) {
        Optional<List<Error>> optionalErrorList = Optional.ofNullable((item.getErrors()));
        if(optionalErrorList.isPresent())
            if (!optionalErrorList.get().isEmpty()) {
                return "failure";
            }
        }
        return "success";
Run Code Online (Sandbox Code Playgroud)

Fed*_*ner 11

Optional并不是要替换if语句,而是用作方法的返回值.所以我认为你最好不要用它来完成这项任务.您可以使用三元运算符Stream.allMatch:

return message.getItems() == null || 
       message.getItems().stream()
              .allMatch(i -> i.getErrors() == null || i.getErrors().isEmpty()) ?
      "success" :
      "failure";
Run Code Online (Sandbox Code Playgroud)

另外,方法永远不应该返回null集合.缺少元素应该通过返回空集合来表达.这会使您的代码更容易:

return message.getItems().stream().allMatch(i -> i.getErrors().isEmpty()) ?
      "success" :
      "failure";
Run Code Online (Sandbox Code Playgroud)

  • +"for Optional"并不意味着替换if语句"和"返回空集合而不是null." 如果我可以两次投票,我会的! (3认同)

MC *_*ror 5

您可以使用flatMap搜索列表中的列表.我个人认为List应该永远不应该null,而应该是一个空列表.如果这是一个保证,那么代码可能是这样的:

boolean hasError = message.getItems().stream()
    .flatMap(t -> t.getErrors().stream())
    .findAny()
    .isPresent();
return (hasError ? "success" : "failure");
Run Code Online (Sandbox Code Playgroud)

否则,代码会变得更长一些:

boolean hasError = Optional.ofNullable(message.getItems()).orElse(List.of()).stream()
    .flatMap(t -> Optional.ofNullable(t.getErrors()).orElse(List.of()).stream())
    .findAny()
    .isPresent();
return (hasError ? "success" : "failure");
Run Code Online (Sandbox Code Playgroud)

请注意,我也可以使用.count() > 0而不是.findAny().isPresent().但前者的缺点是它会遍历所有错误,而后者则会在发现任何错误时发生短路.


Nam*_*man 1

您可以anyMatch将迭代代码用作:

Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
    if (optionalItemList.get().stream()
            .map(item -> Optional.ofNullable((item.getErrors())))
            .filter(Optional::isPresent)
            .anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty())) {
        return "failure";
    }
return "success";
Run Code Online (Sandbox Code Playgroud)

或进一步简化为:

return Optional.ofNullable(message.getItems())
        .filter(a -> a.stream()
                .map(item -> Optional.ofNullable((item.getErrors())))
                .filter(Optional::isPresent)
                .anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty()))
        .map(a -> "failure")
        .orElse("success");
Run Code Online (Sandbox Code Playgroud)