【问题标题】:How to print keys with duplicate values in a hashmap?如何在哈希图中打印具有重复值的键?
【发布时间】:2019-03-22 23:39:39
【问题描述】:

我有一个哈希图,其中一些键指向相同的值。我想找到所有相等的值并打印相应的键。

这是我目前拥有的代码:

    Map<String, String> map = new HashMap<>();

    map.put("hello", "0123");
    map.put("hola", "0123");
    map.put("kosta", "0123");
    map.put("da", "03");
    map.put("notda", "013");

    map.put("twins2", "01");
    map.put("twins22", "01");


    List<String> myList = new ArrayList<>();

    for (Map.Entry<String, String> entry : map.entrySet()) {
       for (Map.Entry<String, String> entry2 : map.entrySet()){
           if (entry.getValue().equals(entry2.getValue()))
           {
               myList.add(entry.getKey());
           }
       }

    }

当前代码将重复项两次添加到列表中,但它也将每个键添加一次。

谢谢。

【问题讨论】:

  • 遍历每个条目。将该值添加到一个新的 Set 中,如果该值已包含在其中,请检查该值。这保证了 O(n) 的运行时间。
  • 如果您关心性能,最好有另一个 HashMap 将您的值存储为映射到数组的键或原始 HashMap 中的键列表。

标签: java hashmap duplicates


【解决方案1】:

您可以通过这种方式使用流来检索重复项:

  List<String> myList = map.stream()
     .filter(n -> Collections.frequency(map.values(), n) > 1)
     .collect(Collectors.toList());

然后,您可以使用以下命令将其打印出来:

myList.foreach(System.out::println);

【讨论】:

    【解决方案2】:

    构建一个Map&lt;VALUE, List&lt;KEY&gt;&gt;,即Map&lt;String, List&lt;String&gt;&gt;

    例子

    Map<String, String> map = new HashMap<>();
    map.put("hello", "0123");
    map.put("hola", "0123");
    map.put("kosta", "0123");
    map.put("da", "03");
    map.put("notda", "013");
    map.put("twins2", "01");
    map.put("twins22", "01");
    
    map.entrySet().stream()
       .collect(Collectors.groupingBy(Entry::getValue,
                   Collectors.mapping(Entry::getKey, Collectors.toList())))
       .entrySet().stream()
       .filter(e -> e.getValue().size() > 1)
       .forEach(System.out::println);
    

    输出

    01=[twins22, twins2]
    0123=[kosta, hello, hola]
    

    没有filter(),结果将是:

    01=[twins22, twins2]
    013=[notda]
    03=[da]
    0123=[kosta, hello, hola]
    

    【讨论】:

      【解决方案3】:

      如果您想要 Stream API 之外的解决方案;

          public static void duplicatedValuesMap() {
              Map<String, String> map = new HashMap<>();
      
              map.put("hello", "0123");
              map.put("hola", "0123");
              map.put("kosta", "0123 test");
              map.put("da", "03");
              map.put("notda", "013");
              map.put("twins2", "01");
              map.put("twins22", "01");
      
              HashMap<String, List<String>> valueToKeyMapCounter = new HashMap<>();
      
              for (Map.Entry<String, String> entry : map.entrySet()) {
                  if (valueToKeyMapCounter.containsKey(entry.getValue())) {
                      valueToKeyMapCounter.get(entry.getValue()).add(entry.getKey());
                  } else {
                      List<String> keys = new ArrayList<>();
                      keys.add(entry.getKey());
                      valueToKeyMapCounter.put(entry.getValue(), keys);
                  }
              }
              for (Map.Entry<String, List<String>> counterEntry : valueToKeyMapCounter.entrySet()) {
                  if (counterEntry.getValue().size() > 1) {
                      System.out.println("Duplicated Value:" + counterEntry.getKey() + " for Keys:" + counterEntry.getValue());
                  }
              }
      
          }
      

      【讨论】:

        【解决方案4】:

        我认为其他答案已经很好地解决了这个问题,我支持另一种方法来做扩展思维。这个方法需要使用GuavaMutliMap接口:

            // init the input map
            Map<String, String> map = new HashMap<>();
            map.put("hello", "0123");
            map.put("hola", "0123");
            map.put("kosta", "0123");
            map.put("da", "03");
            map.put("notda", "013");
            map.put("twins2", "01");
            map.put("twins22", "01");
        
            // swap key and value of the input map,since different key has same value
            // so we need Multimap
            Multimap<String, String> container = ArrayListMultimap.create();
            map.entrySet().forEach(entry -> container.put(entry.getValue(), entry.getKey()));
        
            container.keySet().stream()
                .filter(s -> container.get(s).size() > 1).
                forEach(System.out::println);
        

        输出:
        01
        0123

        【讨论】:

          猜你喜欢
          • 2023-03-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-10
          • 2014-04-15
          • 1970-01-01
          相关资源
          最近更新 更多