Java中流式处理可选嵌套列表的最简洁高效实现方式是什么
优化方案
你原有的写法可以通过抽取通用工具函数大幅简化,同时注意原代码末尾直接调用equals存在逻辑错误:map(Baz::getCode)返回的是Optional<String>类型,直接和字符串判等永远返回false,需要修正。
方案1:抽取通用转换函数(兼容Java 8+)
封装通用的列表取首元素方法,一次性解决空值防护、列表转流、取首元素的逻辑,避免重复代码:
import java.util.List; import java.util.Optional; import java.util.function.Function; // 通用工具方法,可放到公共工具类中 public static <P, C> Function<P, Optional<C>> getFirstFromList(Function<P, List<C>> listExtractor) { return parentObj -> Optional.ofNullable(parentObj) .map(listExtractor) .flatMap(list -> list.stream().findFirst()); }
使用该方法后业务代码可简化为:
boolean codeMatch = Optional.ofNullable(container) .flatMap(getFirstFromList(Container::getFooList)) .flatMap(getFirstFromList(Foo::getBarList)) .flatMap(getFirstFromList(Bar::getBazList)) .map(Baz::getCode) .filter(someBaz.getCode()::equals) .isPresent();
方案2:用Stream拍平链路(Java 9+)
Java 9为Optional新增了stream()方法,你可以直接把整个嵌套链路转成流处理,写法更流畅:
import java.util.Objects; boolean codeMatch = Optional.ofNullable(container) .stream() .map(Container::getFooList) .filter(Objects::nonNull) .flatMap(List::stream) .map(Foo::getBarList) .filter(Objects::nonNull) .flatMap(List::stream) .map(Bar::getBazList) .filter(Objects::nonNull) .flatMap(List::stream) .findFirst() .map(Baz::getCode) .filter(someBaz.getCode()::equals) .isPresent();
补充:校验Baz实例唯一
如果需要严格校验链路中仅存在1个Baz实例,不能直接用findFirst,需要统计Baz的总数量:
long bazTotal = Optional.ofNullable(container) .stream() .map(Container::getFooList) .filter(Objects::nonNull) .flatMap(List::stream) .map(Foo::getBarList) .filter(Objects::nonNull) .flatMap(List::stream) .map(Bar::getBazList) .filter(Objects::nonNull) .flatMap(List::stream) .count(); if (bazTotal == 1) { // 再执行code校验逻辑 }
内容的提问来源于stack exchange,提问作者FerdTurgusen
相关产品推荐
相关产品推荐

