Java8 Stream多层嵌套过滤实现:如何筛选嵌套集合数据?
嘿,我来帮你梳理下这个问题~你当前写的代码逻辑是不可行的,因为Stream.filter()方法要求传入的Lambda表达式必须返回一个boolean值,而你嵌套的x.getCustomDto1List.stream().filter(...)返回的是一个Stream<CustomDto1>对象,这不符合filter()的参数要求,编译器直接会报错。
正确的实现思路
我们的目标是筛选出至少包含一个符合条件的CustomDto1,且该CustomDto1又至少包含一个符合条件的CustomDto2的CustomDto。这里应该用Stream.anyMatch()方法,它会返回布尔值,表示流中是否存在至少一个元素满足给定的条件,完美适配filter()的需求,而且是短路操作(找到第一个符合条件的元素就停止遍历),效率更高。
代码示例
假设你的getter方法都是规范的(比如getCustomDto1List()、getCustomDto2List()、getSomeColumn()),正确的实现代码如下:
List<CustomDto> response = 读取到的数据; List<CustomDto> filteredList = response.stream() .filter(customDto -> // 检查当前CustomDto的CustomDto1列表中是否存在符合条件的元素 customDto.getCustomDto1List().stream() .anyMatch(customDto1 -> // 检查当前CustomDto1的CustomDto2列表中是否存在目标元素 customDto1.getCustomDto2List().stream() .anyMatch(customDto2 -> "XXX".equals(customDto2.getSomeColumn()) // 常量放前面避免空指针 ) ) ) .collect(Collectors.toList());
额外提醒:空指针防护
如果你的集合可能返回null(比如getCustomDto1List()或getCustomDto2List()可能返回null),或者CustomDto2对象本身可能为null,一定要加上非空判断,避免运行时抛出NullPointerException:
List<CustomDto> filteredList = response.stream() .filter(customDto -> customDto.getCustomDto1List() != null && customDto.getCustomDto1List().stream() .anyMatch(customDto1 -> customDto1.getCustomDto2List() != null && customDto1.getCustomDto2List().stream() .anyMatch(customDto2 -> customDto2 != null && "XXX".equals(customDto2.getSomeColumn()) ) ) ) .collect(Collectors.toList());
如果你的需求是不仅过滤外层CustomDto,还要同时过滤内层的CustomDto1和CustomDto2集合(比如只保留符合条件的子元素),那逻辑会更复杂一些,但从你的问题描述来看,应该只是要筛选外层的CustomDto,上面的代码就足够啦。
内容的提问来源于stack exchange,提问作者Randy

