Java中如何在循环中为MultiMap存储不同的键-双值组合
问题场景
我需要在每次循环中获取不同的key、value1和value2,以类似MultiMap的形式(key对应一组value1和value2)存储。但用List配对value1和value2时,新值会不断追加到同一个List中,无法形成独立的键值对。
我的代码
String gid, etype, orid = null; HashMap<String, List<String>> map = new HashMap<>(); List<String> pair = new ArrayList<String>(); while (rs.next()) { gid = rs.getString("gid"); etype = rs.getString("eType"); oid=rs.getString("Orid"); pair.add(entitytype); // 注:此处变量名应为etype pair.add(orderid); // 注:此处变量名应为oid map.put(groupid, pair); // 注:此处变量名应为gid }
期望输出
key1, value1, value2 //loop1
key2, value1, value2 // loop2
实际输出
key1, value1, value2 //loop1
key1, value1, value2, value1, value2 //loop2
问题原因
核心问题是List实例的创建位置错误:你在循环外部只创建了一个pair对象,每次循环都是往同一个List实例中添加元素,再将这个List重复存入HashMap。无论key是否变化,HashMap中所有key指向的都是同一个List对象,导致元素持续累积。
解决方案
方案1:每次循环创建新List(适用于单key对应单组value)
将List的初始化逻辑移到while循环内部,确保每次循环都会生成一个全新的List,仅存储当前循环的value1和value2,再与当前key绑定:
String gid, etype, oid = null; HashMap<String, List<String>> map = new HashMap<>(); while (rs.next()) { gid = rs.getString("gid"); etype = rs.getString("eType"); oid = rs.getString("Orid"); // 每次循环新建List,存储当前组的value List<String> pair = new ArrayList<>(); pair.add(etype); pair.add(oid); map.put(gid, pair); }
方案2:支持单key对应多组value(key可能重复场景)
如果业务中同一个key需要对应多组(value1, value2),则先检查HashMap中是否已存在该key对应的List集合:存在则复用,不存在则新建:
String gid, etype, oid = null; // 外层List存储多组value对,内层List存储单组的两个值 HashMap<String, List<List<String>>> map = new HashMap<>(); while (rs.next()) { gid = rs.getString("gid"); etype = rs.getString("eType"); oid = rs.getString("Orid"); // 检查当前key是否已有对应的集合 List<List<String>> valuePairs = map.get(gid); if (valuePairs == null) { valuePairs = new ArrayList<>(); map.put(gid, valuePairs); } // 新建单组value对并加入集合 List<String> pair = new ArrayList<>(); pair.add(etype); pair.add(oid); valuePairs.add(pair); }
方案3:用自定义类封装value对(可读性更优)
用List存储两个值不够直观,推荐定义一个简单的POJO类来封装value1和value2,代码可读性更强:
// 自定义POJO类,封装两组value class ValuePair { private String eType; private String orid; public ValuePair(String eType, String orid) { this.eType = eType; this.orid = orid; } // 可选:添加getter/setter方法 // 可选:重写toString方便打印输出 @Override public String toString() { return eType + ", " + orid; } } // 使用示例 String gid, etype, oid = null; HashMap<String, ValuePair> map = new HashMap<>(); while (rs.next()) { gid = rs.getString("gid"); etype = rs.getString("eType"); oid = rs.getString("Orid"); map.put(gid, new ValuePair(etype, oid)); }
如果需要单key对应多组ValuePair,只需将HashMap改为HashMap<String, List<ValuePair>>,逻辑参考方案2即可。
内容的提问来源于stack exchange,提问作者Rahul Maurya

