如何用更优雅的函数式方式实现Java Stream多条件提取合并?
函数式风格重构方案
你的核心需求是将命令式的多分支判断转化为契合Stream语境的函数式实现,这里提供两种优雅的重构思路,同时优化类型安全与空值处理:
思路1:基于优先级的Optional匹配
把每个key的提取逻辑按优先级封装成Function,依次尝试匹配,找到第一个存在的key就执行对应提取逻辑,彻底消除嵌套if-else:
private Stream<String> getModelNames(Map<String, Map<String, Object>> expression) { // 按优先级定义提取规则:keyA > keyB > keyC > keyD return Stream.<Function<Map<String, Map<String, Object>>, Optional<Stream<String>>>>of( expr -> Optional.ofNullable(expr.get("keyA")) .map(modelMap -> Stream.of((String) modelMap.get("model_name"))), expr -> Optional.ofNullable(expr.get("keyB")) .map(modelMap -> Stream.of((String) modelMap.get("model_name"))), expr -> Optional.ofNullable(expr.get("keyC")) .map(modelMap -> Stream.of((String) modelMap.get("model_name"))), expr -> Optional.ofNullable(expr.get("keyD")) .map(keyDMap -> ((List<?>) keyDMap.get("cases")).stream() .map(caseItem -> (String) ((List<?>) caseItem).get(1))) ) .map(rule -> rule.apply(expression)) .filter(Optional::isPresent) .findFirst() .orElse(Stream.empty()); }
思路2:封装提取规则列表
把每个key的匹配条件和提取逻辑绑定成规则对象,按优先级遍历规则,找到第一个匹配的规则执行提取,扩展性更强:
// 定义简单的规则类(也可用Tuple替代) private static class ExtractionRule { private final String key; private final Function<Map<String, Object>, Stream<String>> extractor; ExtractionRule(String key, Function<Map<String, Object>, Stream<String>> extractor) { this.key = key; this.extractor = extractor; } boolean matches(Map<String, Map<String, Object>> expr) { return expr.containsKey(key); } Stream<String> extract(Map<String, Map<String, Object>> expr) { return extractor.apply(expr.get(key)); } } private Stream<String> getModelNames(Map<String, Map<String, Object>> expression) { List<ExtractionRule> rules = List.of( new ExtractionRule("keyA", map -> Stream.of((String) map.get("model_name"))), new ExtractionRule("keyB", map -> Stream.of((String) map.get("model_name"))), new ExtractionRule("keyC", map -> Stream.of((String) map.get("model_name"))), new ExtractionRule("keyD", map -> ((List<?>) map.get("cases")).stream() .map(caseItem -> (String) ((List<?>) caseItem).get(1))) ); return rules.stream() .filter(rule -> rule.matches(expression)) .findFirst() .map(rule -> rule.extract(expression)) .orElse(Stream.empty()); }
优化后的完整Stream链
原Stream链可简化,将map+flatMap合并为一步:
List<String> modelNames = ruleRepository .getSomeData() .stream() .map(expr -> (Map<String, Map<String, Object>>) yaml.load(expr)) .flatMap(this::getModelNames) .toList();
额外优化建议
- 类型安全:处理
cases等集合时,先通过instanceof做类型检查,避免强制转换异常 - 空值防护:对
model_name、cases用Optional.ofNullable包裹,避免空指针异常
内容的提问来源于stack exchange,提问作者stasdavydov
相关产品推荐
相关产品推荐

