如何将Map中的重复值映射至其对应的键集合?
解决方案:从原Map提取重复值对应的键集合
刚好碰到过类似的场景,我给你两种实用的实现方案,分别适配不同的Java版本需求:
方法1:Java 8+ Stream API(简洁高效)
如果你的项目已经使用Java 8及以上版本,用Stream API可以写出非常简洁的代码,逻辑清晰且易维护:
import java.util.*; import java.util.stream.Collectors; public class ShopProductMapper { public static void main(String[] args) { // 初始化原Map Map<String, String> shopProductMap = new HashMap<>(); shopProductMap.put("Shop1", "Product1"); shopProductMap.put("Shop2", "Product2"); shopProductMap.put("Shop3", "Product1"); shopProductMap.put("Shop4", "Product2"); shopProductMap.put("Shop5", "Product3"); // 核心逻辑:分组+过滤 Map<String, List<String>> resultMap = shopProductMap.entrySet().stream() // 按产品值分组,收集对应的店铺名称列表 .collect(Collectors.groupingBy( Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList()) )) // 只保留有多个店铺的产品(过滤掉仅出现一次的Product3) .entrySet().stream() .filter(entry -> entry.getValue().size() > 1) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); // 打印验证结果 resultMap.forEach((product, shops) -> System.out.printf("%s -> %s%n", product, String.join(",", shops)) ); } }
代码说明:
- 先用
Collectors.groupingBy完成反转分组:把原Map的value(产品)作为新Map的键,原Map的key(店铺)收集成列表作为新Map的值; - 接着通过
filter过滤掉列表长度≤1的条目,也就是只保留重复出现的产品; - 最后把过滤后的结果重新收集成目标类型的Map。
方法2:传统循环方式(兼容Java 8之前版本)
如果你的项目还在使用Java 7或更早版本,用传统的循环方式也能轻松实现:
import java.util.*; public class ShopProductMapper { public static void main(String[] args) { // 初始化原Map Map<String, String> shopProductMap = new HashMap<>(); shopProductMap.put("Shop1", "Product1"); shopProductMap.put("Shop2", "Product2"); shopProductMap.put("Shop3", "Product1"); shopProductMap.put("Shop4", "Product2"); shopProductMap.put("Shop5", "Product3"); // 第一步:先完成分组,把产品对应的店铺都收集起来 Map<String, List<String>> tempMap = new HashMap<>(); for (Map.Entry<String, String> entry : shopProductMap.entrySet()) { String product = entry.getValue(); String shop = entry.getKey(); // 如果产品还没在临时Map里,就创建一个新的列表 if (!tempMap.containsKey(product)) { tempMap.put(product, new ArrayList<>()); } tempMap.get(product).add(shop); } // 第二步:过滤掉只有单个店铺的产品,得到最终结果 Map<String, List<String>> resultMap = new HashMap<>(); for (Map.Entry<String, List<String>> entry : tempMap.entrySet()) { if (entry.getValue().size() > 1) { resultMap.put(entry.getKey(), entry.getValue()); } } // 打印验证结果 for (Map.Entry<String, List<String>> entry : resultMap.entrySet()) { System.out.printf("%s -> %s%n", entry.getKey(), String.join(",", entry.getValue())); } } }
代码说明:
- 第一次遍历原Map,把每个产品对应的店铺都收集到临时Map的列表中;
- 第二次遍历临时Map,只保留列表长度>1的条目到结果Map中,自动排除掉只出现一次的Product3。
两种方案最终都会输出你期望的结果:
Product1 -> Shop1,Shop3
Product2 -> Shop2,Shop4
内容的提问来源于stack exchange,提问作者Parag Kadam
相关产品推荐
相关产品推荐

