Groovy自定义Comparator过滤数组:保留同ID低优先级type元素
解决方案:Groovy按ID去重并保留低优先级Type元素
核心思路
你的需求是按ID去重,保留同ID中Type优先级更低的元素(优先级顺序:A1 < A2 < R5 < R8 < A4)。removeAll虽能实现,但逻辑较绕且效率偏低,更推荐用分组+筛选的方式;如果坚持用removeAll,也可以实现,下面分别给出两种方案。
方案一:分组筛选(高效简洁)
先按ID分组,每组内用自定义Comparator排序,取优先级最低的元素(排序后的第一个)。
完整代码
// 定义元素类(如果你的数据是Map,可替换为Map操作) class Element { int id String type String text } // 自定义优先级比较器(优化后版本) class CustomComparator implements Comparator<Element>{ private final Map<String, Integer> rank = [ "A1": 1, "A2": 2, "R5": 3, "R8": 4, "A4": 5 ] @Override public int compare(Element a, Element b) { return rank.get(a.type).compareTo(rank.get(b.type)) } } // 初始化示例数据 def elements = [ new Element(id: 1, type: "A1", text: "Bla bla bla 1 - A1"), new Element(id: 2, type: "A1", text: "Bla bla bla 2 - A1"), new Element(id: 3, type: "A1", text: "Bla bla bla 3 - A1"), new Element(id: 1, type: "A2", text: "Bla bla bla 1 - A2") ] def comparator = new CustomComparator() // 分组筛选核心逻辑 def filteredElements = elements.groupBy { it.id } .values() .collect { group -> // 按优先级排序,取第一个(优先级最低的元素) group.sort(comparator).first() } // 输出结果 println(filteredElements)
代码说明
- groupBy(it.id):将元素按ID分组,同ID的元素归为一组;
- sort(comparator):每组内用自定义比较器排序,优先级低的元素会排在前面;
- first():取排序后的第一个元素,就是我们要保留的低优先级元素。
方案二:使用removeAll实现
如果一定要用removeAll,逻辑是:遍历每个元素,若存在同ID且优先级更低的元素,则移除当前元素。
完整代码
// 复用上面的Element类和CustomComparator类 def elements = [ new Element(id: 1, type: "A1", text: "Bla bla bla 1 - A1"), new Element(id: 2, type: "A1", text: "Bla bla bla 2 - A1"), new Element(id: 3, type: "A1", text: "Bla bla bla 3 - A1"), new Element(id: 1, type: "A2", text: "Bla bla bla 1 - A2") ] def comparator = new CustomComparator() // removeAll逻辑:返回true的元素会被移除 elements.removeAll { current -> // 检查是否存在同ID且优先级比当前元素低的元素 elements.any { other -> other.id == current.id && comparator.compare(other, current) < 0 } } // 输出结果 println(elements)
代码说明
- comparator.compare(other, current) < 0:表示
other的优先级比current低; - 如果存在这样的
other,说明current是需要被移除的高优先级元素,removeAll会将其删除。
注意事项
- 若你的原始数据是
Map而非自定义类,只需将代码中的it.id改为it.get("id"),it.type改为it.get("type"),同时调整Comparator的泛型为Map即可; - 分组方案的时间复杂度为O(n log n),
removeAll方案为O(n²),数据量大时优先选分组方案。
内容的提问来源于stack exchange,提问作者andQlimax
相关产品推荐
相关产品推荐

