Java中List<HashMap<String, Object>>的交集、差集实现问题
问题说明
需要计算两个List<HashMap<String, Object>>的交集和差集,但当前使用removeAll和retainAll仅返回true/false(表示集合是否被修改),无法获取实际的集合数据。期望结果:
- 差集:
[{prodCode=KR7279570006, accountNum=20101834049, orgCode=C1AACQ0000}] - 交集:
[{prodCode=KR7020150009, accountNum=20402786856, orgCode=C1AACQ0000}, {prodCode=KR7020150009, accountNum=20101834049, orgCode=C1AACQ0000}]
当前代码及输出:
List<HashMap<String, Object>> stockListInDb = [{prodCode=KR7020150009, accountNum=20402786856, orgCode=C1AACQ0000}, {prodCode=KR7020150009, accountNum=20101834049, orgCode=C1AACQ0000}] List<HashMap<String, Object>> presentedStockList = [{prodCode=KR7020150009, accountNum=20402786856, orgCode=C1AACQ0000}, {prodCode=KR7020150009, accountNum=20101834049, orgCode=C1AACQ0000}, {prodCode=KR7279570006, accountNum=20101834049, orgCode=C1AACQ0000}] System.out.println("새로운 주식은 " + presentedStockList.removeAll(stockListInDb) ); System.out.println("홀딩한 주식은 " + stockListInDb.retainAll(presentedStockList));
输出:
새로운 주식은 true 홀딩한 주식은 true
解决方案
removeAll和retainAll的返回值仅表示集合是否被修改,不会返回结果集合,且会直接修改原列表。要获取实际的交集/差集,需基于原列表的副本操作,或使用Stream API过滤。
方法一:基于集合副本操作
先复制原列表,避免破坏原始数据,再通过集合方法得到结果:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class StockSetDemo { public static void main(String[] args) { // 初始化原始数据 List<HashMap<String, Object>> stockListInDb = new ArrayList<>(); HashMap<String, Object> stock1 = new HashMap<>(); stock1.put("prodCode", "KR7020150009"); stock1.put("accountNum", "20402786856"); stock1.put("orgCode", "C1AACQ0000"); stockListInDb.add(stock1); HashMap<String, Object> stock2 = new HashMap<>(); stock2.put("prodCode", "KR7020150009"); stock2.put("accountNum", "20101834049"); stock2.put("orgCode", "C1AACQ0000"); stockListInDb.add(stock2); List<HashMap<String, Object>> presentedStockList = new ArrayList<>(); presentedStockList.add(stock1); presentedStockList.add(stock2); HashMap<String, Object> stock3 = new HashMap<>(); stock3.put("prodCode", "KR7279570006"); stock3.put("accountNum", "20101834049"); stock3.put("orgCode", "C1AACQ0000"); presentedStockList.add(stock3); // 求差集:presentedStockList独有的元素 List<HashMap<String, Object>> diffList = new ArrayList<>(presentedStockList); diffList.removeAll(stockListInDb); System.out.println("새로운 주식은 " + diffList); // 求交集:两个列表共有的元素 List<HashMap<String, Object>> intersectionList = new ArrayList<>(stockListInDb); intersectionList.retainAll(presentedStockList); System.out.println("홀딩한 주식은 " + intersectionList); } }
输出:
새로운 주식은 [{prodCode=KR7279570006, accountNum=20101834049, orgCode=C1AACQ0000}] 홀딩한 주식은 [{prodCode=KR7020150009, accountNum=20402786856, orgCode=C1AACQ0000}, {prodCode=KR7020150009, accountNum=20101834049, orgCode=C1AACQ0000}]
方法二:使用Stream API过滤
无需修改集合,直接通过Stream过滤出结果:
// 求差集 List<HashMap<String, Object>> diffList = presentedStockList.stream() .filter(item -> !stockListInDb.contains(item)) .toList(); // 求交集 List<HashMap<String, Object>> intersectionList = stockListInDb.stream() .filter(presentedStockList::contains) .toList(); System.out.println("새로운 주식은 " + diffList); System.out.println("홀딩한 주식은 " + intersectionList);
注意事项
- Java原生
HashMap已正确实现equals和hashCode方法,只要两个HashMap的键值对完全一致,就会被判定为相等,因此可以直接使用contains、removeAll、retainAll方法。 - 操作时务必使用原列表的副本,避免原始数据被意外修改。
内容的提问来源于stack exchange,提问作者broheat
相关产品推荐
相关产品推荐

