Groovy合并YAML配置文件时去除列表重复元素的实现咨询
YAML配置嵌套合并+列表去重实现方案
针对嵌套结构YAML合并、列表重复项去除的场景,基于Groovy实现定制化合并逻辑即可,不需要依赖第三方合并工具的默认行为(默认的嵌套Map合并遇到列表会直接覆盖或者全量追加,容易产生重复项)。
核心合并规则
- 普通嵌套Map字段:递归向下合并,不存在的字段完整保留
- 列表类字段:不做直接追加或覆盖,先做重复校验,仅追加不存在的新元素
- 同值字段冲突:可按业务优先级选择保留高优先级配置的内容
可直接复用的Groovy合并代码
// 自定义列表重复判定逻辑:对比配置项所有键值对完全一致即为重复 def isItemDuplicate = (List existingItems, Object newItem) -> { existingItems.any { existingItem -> existingItem == newItem } } def deepMergeWithDedup = (Map configFirst, Map configSecond) -> { Map mergedResult = new LinkedHashMap<>(configFirst) configSecond.each { key, secondValue -> def firstValue = mergedResult.get(key) // 同字段均为Map结构,递归执行深合并 if (firstValue instanceof Map && secondValue instanceof Map) { mergedResult.put(key, deepMergeWithDedup(firstValue as Map, secondValue as Map)) } // 同字段均为List结构,走去重追加逻辑 else if (firstValue instanceof List && secondValue instanceof List) { List mergedList = new ArrayList<>(firstValue as List) (secondValue as List).each { item -> if (!isItemDuplicate(mergedList, item)) { mergedList.add(item) } } mergedResult.put(key, mergedList) } // 目标字段仅在第二份配置存在,直接赋值 else if (!mergedResult.containsKey(key)) { mergedResult.put(key, secondValue) } } return mergedResult }
效果匹配说明
用你提供的两份示例配置转换成Map后传入上述方法,最终输出的结构完全符合预期:
tool: jdk: - name: jdk8 version: 8 - name: jdk11 version: 11 - name: jdk15 version: 15
灵活调整提示
- 如果列表的重复判定规则需要按指定唯一键(比如只要配置项的
name字段相同就算重复,忽略其他字段差异),只需要修改isItemDuplicate方法的判断逻辑,仅对比指定字段即可 - 如果需要调整合并优先级(比如字段值冲突时优先使用第二份配置的内容),只需要在Map赋值、列表覆盖的分支调整取值逻辑即可
内容的提问来源于stack exchange,提问作者Raphael Perrin
相关产品推荐
相关产品推荐

