Java 8中实现Map<Key, List<Value>>转Map<Value, Key>的方法
反转Map<String, List>为Map<Integer, String>的实现方案
没问题,这个需求其实挺常见的,我来给你两种实用的实现方式,分别适配不同Java版本,顺便聊聊需要注意的细节。
方式一:传统循环实现(兼容Java 8之前版本)
这种方式逻辑直白,容易理解,适合所有Java版本:
// 初始化原Map(你提供的示例代码) Map<String, List<Integer>> mapOfIntList = new HashMap<>(); mapOfIntList.put("UNIT", Arrays.asList(1, 2, 3, 8, 7, 0, 8, 6)); mapOfIntList.put("TEN", Arrays.asList(24, 90, 63, 87)); mapOfIntList.put("HUNDRED", Arrays.asList(645, 457, 306, 762)); mapOfIntList.put("THOUSAND", Arrays.asList(1234, 3456, 5340, 9876)); // 反转逻辑 Map<Integer, String> reversedMap = new HashMap<>(); for (Map.Entry<String, List<Integer>> entry : mapOfIntList.entrySet()) { String originalKey = entry.getKey(); // 遍历原Map中每个Key对应的Integer列表 for (Integer num : entry.getValue()) { // 将数字作为新Key,原Key作为Value存入新Map reversedMap.put(num, originalKey); } }
注意点:
- 如果不同的原Key下存在相同的Integer,后处理的那个会覆盖先存入的(比如如果"TEN"里也有个8,那最后reversedMap里的8会对应"TEN"而不是"UNIT")。如果需要自定义重复Key的处理逻辑,可以在put前判断是否已存在。
- 如果原List中包含
null值,新Map的Key会是null,如果业务不允许,可在循环里加if (num != null)过滤。
方式二:Java 8+ Stream流实现(更简洁优雅)
如果你用的是Java 8及以上版本,用Stream可以写出更简洁的代码,还能灵活处理重复Key:
Map<Integer, String> reversedMap = mapOfIntList.entrySet() .stream() // 把每个原Entry拆分成多个<数字, 原Key>的Entry .flatMap(entry -> entry.getValue() .stream() .map(num -> new AbstractMap.SimpleEntry<>(num, entry.getKey()))) // 收集成目标Map,第三个参数是重复Key的处理策略 .collect(Collectors.toMap( Map.Entry::getKey, // 提取新Map的Key(数字) Map.Entry::getValue, // 提取新Map的Value(原Key) (oldVal, newVal) -> oldVal // 遇到重复Key时保留旧值,换成newVal则保留新值 ));
逻辑说明:
flatMap的作用是把每个原Map的Entry(对应一个Key和一个List),拆分成多个独立的<数字, 原Key>键值对。Collectors.toMap的第三个参数是关键:当遇到重复的数字Key时,你可以指定保留旧值还是新值,完全根据业务需求调整。
不管用哪种方式,最终都能得到你想要的(1, "UNIT")、(24, "TEN")这类映射关系。
内容的提问来源于stack exchange,提问作者Sentary




