我有一个代码片段,我想使其更简洁但更具可读性 使用 Java 8 功能,如 lambdas/streams 等。
基本上,有一个项目列表,每个项目都有一个错误列表。 如果至少有一项至少有一个错误,则需要返回“失败”。如果没有任何错误,则返回“成功”。
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";
Optional
并不是要取代if
语句,而是用作方法的返回值。所以我认为你最好不要用它来完成这项任务。您可以将三元运算符与 Stream.allMatch
一起使用:
return message.getItems() == null ||
message.getItems().stream()
.allMatch(i -> i.getErrors() == null || i.getErrors().isEmpty()) ?
"success" :
"failure";
顺便说一句,方法永远不应该返回
null
集合。缺少元素应通过返回空集合来表示。这会让你的代码变得更容易:
return message.getItems().stream().allMatch(i -> i.getErrors().isEmpty()) ?
"success" :
"failure";
您可以使用
flatMap
在列表中搜索列表。我个人认为 List
应该 never 是 null
,相反它应该是一个空列表。如果这是一个保证,那么代码可能是这样的:
boolean hasError = message.getItems().stream()
.flatMap(t -> t.getErrors().stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
不然代码会变得有点长:
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");
请注意,我也可以使用
.count() > 0
代替 .findAny().isPresent()
。但前者的缺点是它会迭代所有错误,而后者如果发现任何错误就会短路。
对我来说,你让它变得过于复杂。这是一种更简单的方法。如果没有要返回的项目,请确保您的
getItems()
方法返回一个空列表,以便您可以免除如上所述的额外空检查。这种方法不太容易出错,并且可以生成更具可读性的代码。如果您可以对上面的 getErrors
方法执行相同的操作,则只需省略 filter(Objects::nonNull)
即可,这将进一步简化流处理管道。
String errorPresent = message.getItems().stream()
.map(Item::getErrors).filter(Objects::nonNull)
.map(List::size).filter(s -> s > 0)
.findAny().map(ignored -> "failure")
.orElse("success");
或者,您可以使用三元运算符来完成此操作。
String errorPresent = message.getItems().stream()
.map(Item::getErrors)
.filter(Objects::nonNull)
.anyMatch(e -> !e.isEmpty()) ? "failure" : "success";
您可以使用
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";
或者进一步简化为:
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");
例如,如果您有以下关系
class Parent {
...
List<Child> children;
...
}
您可以简单地执行以下操作,从
Child
列表中获取所有非空 Parent
(子级)。
List<Child> children = parents.stream()
.map(Parent::getChildren)
.filter(CollectionUtils::isNotEmpty) // You can use Apache commons/ Spring framework or your custom util method
.flatMap(Collection::stream)
.toList();
希望这有帮助!