Java 如何在HashMap中找到与最大值关联的键?

Java 如何在HashMap中找到与最大值关联的键?,java,data-structures,indexing,hashmap,Java,Data Structures,Indexing,Hashmap,我想在HashMap中找到与最大值关联的键 我已经看到了这个问题,但是在使用HashMap时有一些限制 任何帮助都将不胜感激。只要您承诺映射的类型为HashMap,您将不会比迭代映射中的所有键/值对来寻找最大值更好。这样的哈希表是在内部组织的,以便通过哈希代码最大限度地查找密钥;组织对与这些键相关联的值漠不关心 为了最好地解决您的问题,您需要对值进行反向索引。由于多个键可以在原始贴图中具有相同的值(假设它不是a),因此反转索引实际上是一个多重贴图,其中任何给定的整数键(取自原始贴图值的整数键集)

我想在
HashMap
中找到与最大值关联的键

我已经看到了这个问题,但是在使用
HashMap
时有一些限制


任何帮助都将不胜感激。

只要您承诺映射的类型为
HashMap
,您将不会比迭代映射中的所有键/值对来寻找最大值更好。这样的哈希表是在内部组织的,以便通过哈希代码最大限度地查找密钥;组织对与这些键相关联的值漠不关心

为了最好地解决您的问题,您需要对值进行反向索引。由于多个键可以在原始贴图中具有相同的值(假设它不是a),因此反转索引实际上是一个多重贴图,其中任何给定的整数键(取自原始贴图值的整数键集)都可以与任意数量的整数值(原始贴图键)相关联

如果反向索引的类型为
NavigableMap
,且值类型为整数集合,则可以使用该方法查找最大整数键与其对应值的配对。或者,如果您手中只有一个
SortedMap
,您仍然可以使用它的方法来查找有问题的密钥。这假设映射是按整数的自然顺序排列的,从最低到最高

提供,其中类型公开了类型
SortedMap
及其方法的视图。我建议你先试试那个


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

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;
  }
}

publicstatic您可以在这里对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;
}
公共LinkedHashMap sortHashMapByValues(HashMap passedMap){
List mapKeys=new ArrayList(passedMap.keySet());
List mapValues=new ArrayList(passedMap.values());
Collections.sort(映射值);
Collections.sort(映射键);
LinkedHashMap-sortedMap=
新建LinkedHashMap();
迭代器值It=mapValues.Iterator();
while(valueIt.hasNext()){
Object val=valueIt.next();
迭代器keyIt=mapKeys.Iterator();
while(keyIt.hasNext()){
int key=(整数)keyIt.next();
int comp1=(整数)passedMap.get(键);
int comp2=(整数)val;
if(comp1==comp2){
passedMap.remove(密钥);
mapKeys.remove(key);
分类地图输入(键,(整数)值);
打破
}
}
}
返回分拣的DMAP;
}

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

因为
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();
比较器比较器= 新比较器(){ 公共整数比较( 地图条目e1,地图条目e2){ 返回e1.getValue().compareTo(e2.getValue()); } }; 返回Collections.max(map.entrySet(),comparator.getKey();
如果您想要所有与最大值相关联的键,这就有点棘手了;你可能会这样做

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());
  }
}
Integer bestSeenValue=null;
List bestKeys=new ArrayList();
对于(Map.Entry:Map.entrySet()){
if(bestSeenValue==null | | entry.getValue()>bestSeenValue){
bestSeenValue=entry.getValue();
bestKeys.clear();
}
if(entry.getValue().equals(bestSeenValue)){
添加(entry.getKey());
}
}

此代码将以最大值打印所有钥匙

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
            }
        }

    }
}
公共类NewClass4{
公共静态void main(字符串[]args)
{
HashMap=新的HashMap();
地图.put(1,50);
地图.put(2,60);
地图.put(3,30);
地图.put(4,60);
地图.put(5,60);
int maxValueInMap=(Collections.max(map.values());//这将在Hashmap中返回最大值
对于(条目:map.entrySet()){//i通过hashmap创建
if(entry.getValue()==maxValueInMap){
System.out.println(entry.getKey());//使用最大值打印密钥
}
}
}
}

Map是什么意思:
Map。如果是HashMap,条目
无效?您的解决方案的性能远不如O(2n)步来查找最大值,然后收集与该值匹配的键。那么这是否令人满意?我想要的是简单而不是原始速度,但我认为这两者都能做到。请参阅我在下面的答案中提出的O(n)解决方案。Hmmmm。我认为我的解决方案可能更快,因为它只进行单次传递,但无论如何它可能是一次清洗…没有泛型?这是什么,2002年?