从仅包含重复值的映射中提取子图

Extract submap from a map that contains only duplicate values

我正在寻找以下问题的最佳或次优解决方案:

Hp: 我们有一张 Java8 地图: Map: {0 -> object0, 1 -> object0, 2->object1, ...., n- >objectN}

目标: return 仅包含具有相同对象的原始地图的键值元素的地图(子地图)的解决方案: Map: {0 -> object0, 1 -> object0}

我找到了获取重复列表的解决方案,但没有找到获取仅包含重复值的新地图的解决方案。

感谢支持

你可以试试这个:

Map<Object, Map<String, Object>> subMaps = 
    map.entrySet()
       .stream()
       .collect(groupingBy(Map.Entry::getValue,
                           toMap(Map.Entry::getKey, Map.Entry::getValue)));

这将为您 return 地图中的地图。

因此,如果您想要仅包含 object0 的子图,请执行以下操作:

Map<String, Object> subMap = subMaps.get(object0);

如果您对所有的子图都不感兴趣,而是想寻找一个特定的值,那么可以这样做:

Map<String, Object> subMapForObject1 = 
    map.entrySet()
       .stream()
       .filter(e -> object1.equals(e.getValue());
       .collect(toMap(Map.Entry::getKey, Map.Entry::getValue)));

一个简单的解决方案是:

  1. 建立临时倒置地图Map<Object, List<Integer>>
  2. 过滤倒置地图以仅保留重复项
  3. 使用flatMap恢复初始Map<Integer, Object>
Map<Integer, Object> map = Map.of(
    0, "object0", 1, "object0", 2, "objectA", 3, "objectZ", 4, "objectZ"
);
System.out.println(map);

Map<Integer, Object> filtered = map.entrySet().stream()
            .collect(Collectors.groupingBy(
                Map.Entry::getValue, 
                Collectors.mapping(Map.Entry::getKey, Collectors.toList())
            ))
            .entrySet().stream() // Stream<Map.Entry<Object, List<Integer>>>
            .filter(e -> e.getValue().size() > 1) // keep duplicates
            .flatMap(e -> e.getValue().stream().map(v -> Map.entry(v, e.getKey())))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(filtered);

输出:

{0=object0, 1=object0, 2=objectA, 3=objectZ, 4=objectZ}
{0=object0, 1=object0, 3=objectZ, 4=objectZ}

更新

@Andreas 建议的更简单的解决方案是:

Map<Integer, Object> filtered2 = map.entrySet().stream()
            .collect(Collectors.groupingBy(Map.Entry::getValue))
            .entrySet().stream() // Stream<Map.Entry<Object, List<Map.Entry<Integer, Object>>>
            .filter(e -> e.getValue().size() > 1) // keep duplicates
            .flatMap(e -> e.getValue().stream())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(filtered2);

输出同上:

{0=object0, 1=object0, 3=objectZ, 4=objectZ}