如何基于Map字段对比两个List<Map<String,Object>>并筛选差异数据
解决List<Map<String, Object>>按指定字段筛选差异数据的问题
为什么直接用contains方法无效
List的contains()方法依赖于元素的equals()实现,而Map的默认equals()是对比所有键值对是否完全一致,不是只看你关心的"cod"字段。所以即使两个Map的"cod"相同,但其他字段不同,contains()会认为是不同的对象;反过来,你要筛选的是"cod"不在list1中的元素,直接用contains()根本匹配不到你要的逻辑。
解决方案
方法一:先提取list1的cod集合,再遍历筛选
先把list1里所有的"cod"值提取到Set中(Set的查询效率远高于List),再遍历list2,判断每个Map的"cod"是否不在这个Set里,符合条件的就加入listNew。
示例代码:
// 提取list1中所有cod值到Set,提升查询效率 Set<Object> list1CodSet = new HashSet<>(); for (Map<String, Object> map : list1) { list1CodSet.add(map.get("cod")); } // 筛选list2中cod不在list1里的元素 List<Map<String, Object>> listNew = new ArrayList<>(); for (Map<String, Object> map : list2) { Object cod = map.get("cod"); if (!list1CodSet.contains(cod)) { listNew.add(map); } }
方法二:用Stream API简化代码(Java 8+)
利用Stream的链式操作,代码更简洁:
Set<Object> list1CodSet = list1.stream() .map(map -> map.get("cod")) .collect(Collectors.toSet()); List<Map<String, Object>> listNew = list2.stream() .filter(map -> !list1CodSet.contains(map.get("cod"))) .collect(Collectors.toList());
注意事项
- 如果"cod"字段可能为空,要添加非空校验,比如
map.get("cod") != null && !list1CodSet.contains(map.get("cod")) - 如果需要避免后续修改原集合影响listNew,可以在添加时创建Map的副本:
listNew.add(new HashMap<>(map))
内容的提问来源于stack exchange,提问作者Luis Fernando Yepes Molina
相关产品推荐
相关产品推荐

