【问题标题】:How do I find the keys associated with the maximum value in HashMap?如何在 HashMap 中找到与最大值关联的键?
【发布时间】:2012-06-28 13:14:16
【问题描述】:

我想在HashMap<Integer,Integer> 中找到与最大值关联的键。

我看到了Finding Key associated with max Value in a Java Map的问题,但是使用HashMap有一定的限制。

任何帮助将不胜感激。

【问题讨论】:

  • 什么意思:Map.Entry 在 HashMap 的情况下无效?

标签: java data-structures indexing hashmap


【解决方案1】:

您可以在这里做的只是对您的 HashMap 进行排序并选择第一个或最后一个键以获得最大值或最小值。

public LinkedHashMap<Integer,Integer> sortHashMapByValues(HashMap<Integer,Integer> passedMap) {
   List<Integer> mapKeys = new ArrayList<Integer>(passedMap.keySet());
   List<Integer> mapValues = new ArrayList<Integer>(passedMap.values());
   Collections.sort(mapValues);
   Collections.sort(mapKeys);

   LinkedHashMap<Integer,Integer> sortedMap = 
       new LinkedHashMap<Integer,Integer>();

   Iterator valueIt = mapValues.iterator();
   while (valueIt.hasNext()) {
       Object val = valueIt.next();
    Iterator keyIt = mapKeys.iterator();

    while (keyIt.hasNext()) {
        int key = (Integer)keyIt.next();
        int comp1 = (Integer)passedMap.get(key);
        int comp2 = (Integer)val;

        if (comp1 == comp2){
            passedMap.remove(key);
            mapKeys.remove(key);
            sortedMap.put(key,(Integer) val);
            break;
        }

    }

}
return sortedMap;
}

请记住 - 它们可能有多个具有相同值的键。

【讨论】:

  • ...没有泛型?这是什么,2002 年?
【解决方案2】:

由于HashMap 没有排序,最简单的解决方案可能是最好的。如果你只想要一个键,那么它只是

Comparator<Map.Entry<Integer, Integer>> comparator =
  new Comparator<Map.Entry<Integer, Integer>>() {
    public int compare(
        Map.Entry<Integer, Integer> e1, Map.Entry<Integer, Integer> e2) {
      return e1.getValue().compareTo(e2.getValue());
    }
};
return Collections.max(map.entrySet(), comparator).getKey();

如果你想要 all 与最大值关联的键,那就有点棘手了;你可能会做类似的事情

Integer bestSeenValue = null;
List<Integer> bestKeys = new ArrayList<>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
  if (bestSeenValue == null || entry.getValue() > bestSeenValue) {
    bestSeenValue = entry.getValue();
    bestKeys.clear();
  }
  if (entry.getValue().equals(bestSeenValue)) {
    bestKeys.add(entry.getKey());
  }
}

【讨论】:

  • 您的解决方案的性能远不如通过 O(2n) 步找到最大值然后收集与该值匹配的键。
  • 这样满意吗?我想要简单而不是原始速度,但我认为这两者都能做到。
  • 在下面的答案中查看我提出的 O(n) 解决方案。
  • 嗯。我认为我的解决方案可能更快,因为它只执行单次通过,但无论如何它可能是一次洗涤。
【解决方案3】:

只要您承诺映射为HashMap 类型,您就不会比遍历映射中的所有键/值对以寻找最大值更好。这样的哈希表是在内部组织的,以便通过它们的哈希码找到 keys 的最大速度;该组织对与这些键关联的值漠不关心。

为了最好地解决您的问题,您需要在值上设置一个倒排索引。由于原始映射中的多个键可以具有相同的值(假设它不是 bijection),因此倒排索引实际上是一个 multimap,其中任何给定的整数键(取自这是您的原始地图值)可以与任意数量的整数值(这是您的原始地图键)相关联。

如果你的倒排索引是NavigableMap类型,值类型是整数的集合,那么你可以使用NavigableMap#lastEntry()方法找到最大整数键和对应值的配对。或者,如果您手头只有一个SortedMap,您仍然可以使用它的SortedMap#lastKey() 方法来查找有问题的密钥。这假设地图是按整数的自然顺序排列的,从最低到最高。

Guava library 提供a set of multimap types,其中TreeMultimap 类型通过其TreeMultimap#asMap() 方法公开SortedMap 类型的视图。我建议您先尝试使用那个。


如果您只需要一次为给定的输入映射找到此答案,并且不想费心构建整个倒排索引,请尝试以下 O(n) em> 解决方案:

public static <T extends Number & Comparable<? super T>>
Collection<? extends T> keysForMaxValueIn(Map<? extends T, ? extends T> map) {
  final int size = map.size();
  switch (size) {
    case 0:
      return Collections.emptySet();
    case 1:
      return Collections.singleton(map.keySet().iterator().next());
    default:
      final T max = Collections.max(map.values());
      // We know that there will be no duplicates in the original key set.        
      final Collection<T> keys = new ArrayList<T>(size);
      for (Map.Entry<? extends T, ? extends T> entry : map.entrySet())
        if (max.equals(entry.getValue()))
          keys.add(entry.getKey());
      return keys;
  }
}

【讨论】:

    【解决方案4】:

    此代码将打印所有具有最大值的键

    public class NewClass4 {
        public static void main(String[] args)
        {
            HashMap<Integer,Integer>map=new HashMap<Integer, Integer>();
            map.put(1, 50);
            map.put(2, 60);
            map.put(3, 30);
            map.put(4, 60);
            map.put(5, 60);
            int maxValueInMap=(Collections.max(map.values()));  // This will return max value in the Hashmap
            for (Entry<Integer, Integer> entry : map.entrySet()) {  // Itrate through hashmap
                if (entry.getValue()==maxValueInMap) {
                    System.out.println(entry.getKey());     // Print the key with max value
                }
            }
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-12
      • 1970-01-01
      • 2011-08-20
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多