如何使用Java Stream基于list2的嵌套对象过滤CarModel类的list1
实现方案
前置说明
以下实现基于Java 8+版本,所有涉及的类的私有属性需提前提供对应的public getter方法用于属性读取。
具体实现步骤
1. 从list2提取所有通配modelName集合
先扁平化遍历list2的嵌套结构,提取所有Car对象的modelName存入Set去重,避免重复匹配提升效率:
import java.util.Set; import java.util.stream.Collectors; Set<String> wildcardModelNames = list2.stream() .flatMap(carData -> carData.getCarDetails().stream()) .flatMap(carDetails -> carDetails.getCars().stream()) .map(Car::getModelName) .collect(Collectors.toSet());
2. 实现*通配匹配方法
支持单/多个*通配符,匹配任意长度的任意字符,同时规避原字符串中正则特殊字符的影响:
import java.util.regex.Pattern; private boolean isModelMatch(String targetModel, String wildcardPattern) { // 转义正则特殊字符,避免原字符串中的.、+等字符干扰匹配 String escapedPattern = Pattern.quote(wildcardPattern) // 将通配符*替换为正则任意匹配规则 .replace("*", "\\E.*\\Q"); return Pattern.matches("^" + escapedPattern + "$", targetModel); }
3. 过滤list1得到目标结果
遍历list1的CarModel对象,仅保留model匹配任意一条通配规则的对象:
import java.util.List; import java.util.stream.Collectors; List<CarModel> filteredList = list1.stream() .filter(carModel -> wildcardModelNames.stream() .anyMatch(pattern -> isModelMatch(carModel.getModel(), pattern))) .collect(Collectors.toList());
性能优化建议
如果list2中的通配规则数量较多,可提前将通配符预编译为Pattern对象,避免每次匹配重复编译正则,提升执行效率:
Set<Pattern> patternSet = wildcardModelNames.stream() .map(pattern -> { String escaped = Pattern.quote(pattern).replace("*", "\\E.*\\Q"); return Pattern.compile("^" + escaped + "$"); }) .collect(Collectors.toSet()); List<CarModel> filteredList = list1.stream() .filter(carModel -> patternSet.stream() .anyMatch(pattern -> pattern.matcher(carModel.getModel()).matches())) .collect(Collectors.toList());
效果验证
按照你给出的示例,最终得到的filteredList会仅保留model为BMW-500-7S-150-Z100、MERCEDES-700-7S-350-Z100的两个CarModel对象,自动过滤掉AUDI对应的对象,符合需求。
内容的提问来源于stack exchange,提问作者piqueblinders
相关产品推荐
相关产品推荐

