【问题标题】:Finding Key associated with max Value in a Java Map在 Java Map 中查找与最大值关联的键
【发布时间】:2011-08-20 03:36:35
【问题描述】:

获取与地图中的最大值关联的键的最简单方法是什么?

我相信 Collections.max(someMap) 会在您想要与最大值对应的键时返回最大键。

【问题讨论】:

    标签: java hashmap


    【解决方案1】:

    最简单的方法是:

    Collections.max(hmap.values());
    

    【讨论】:

    • 这将返回最大的value,而不是与其关联的最大key
    【解决方案2】:

    1.使用流

    public <K, V extends Comparable<V>> V maxUsingStreamAndLambda(Map<K, V> map) {
        Optional<Entry<K, V>> maxEntry = map.entrySet()
            .stream()
            .max((Entry<K, V> e1, Entry<K, V> e2) -> e1.getValue()
                .compareTo(e2.getValue())
            );
         
        return maxEntry.get().getKey();
    }
    

    2。将 Collections.max() 与 Lambda 表达式一起使用

        public <K, V extends Comparable<V>> V maxUsingCollectionsMaxAndLambda(Map<K, V> map) {
            Entry<K, V> maxEntry = Collections.max(map.entrySet(), (Entry<K, V> e1, Entry<K, V> e2) -> e1.getValue()
                .compareTo(e2.getValue()));
            return maxEntry.getKey();
        }
    

    3。将 Stream 与方法参考一起使用

        public <K, V extends Comparable<V>> V maxUsingStreamAndMethodReference(Map<K, V> map) {
            Optional<Entry<K, V>> maxEntry = map.entrySet()
                .stream()
                .max(Map.Entry.comparingByValue());
            return maxEntry.get()
                .getKey();
        }
    

    4.使用 Collections.max()

        public <K, V extends Comparable<V>> V maxUsingCollectionsMax(Map<K, V> map) {
            Entry<K, V> maxEntry = Collections.max(map.entrySet(), new Comparator<Entry<K, V>>() {
                public int compare(Entry<K, V> e1, Entry<K, V> e2) {
                    return e1.getValue()
                        .compareTo(e2.getValue());
                }
            });
            return maxEntry.getKey();
        }
    

    5.使用简单迭代

    public <K, V extends Comparable<V>> V maxUsingIteration(Map<K, V> map) {
        Map.Entry<K, V> maxEntry = null;
        for (Map.Entry<K, V> entry : map.entrySet()) {
            if (maxEntry == null || entry.getValue()
                .compareTo(maxEntry.getValue()) > 0) {
                maxEntry = entry;
            }
        }
        return maxEntry.getKey();
    }
    

    【讨论】:

    • 3. Using Stream with Method Reference 很酷。
    【解决方案3】:

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

    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()) {  // Iterate through HashMap
                if (entry.getValue()==maxValueInMap) {
                    System.out.println(entry.getKey());     // Print the key with max value
                }
            }
    
        }
    }
    

    【讨论】:

    • 应该是“Map.Entry entry: valmap.entrySet()”
    【解决方案4】:

    这将返回 Map&lt;Integer, Integer&gt; 中具有最大值的键

    public Set<Integer> getMaxKeys(Map<Integer, Integer> map) { 
    
            if (map.isEmpty()) {
                return Collections.emptySet();
            }
    
            return map
            .entrySet()
            .stream()
            .collect(
                groupingBy(
                    Map.Entry::getValue, TreeMap::new, mapping(Map.Entry::getKey, toSet())
                )
             )
             .lastEntry()
             .getValue();
        }
    

    【讨论】:

      【解决方案5】:

      简单易懂。 在下面的代码中,maxKey 是保存最大值的键。

      int maxKey = 0;
      int maxValue = 0;
      for(int i : birds.keySet())
      {
          if(birds.get(i) > maxValue)
          {
              maxKey = i;
              maxValue = birds.get(i);
          }
      }
      

      【讨论】:

        【解决方案6】:

        给定地图

        HashMap abc = new HashMap();

        获取具有最大值的所有地图条目。

        您可以在过滤器中使用以下任何方法来获取最小值或最大值集的相应映射条目

        Collections.max(abc.values())
        Collections.min(abc.values())
        Collections.max(abc.keys())
        Collections.max(abc.keys())
        
        abc.entrySet().stream().filter(entry -> entry.getValue() == Collections.max(abc.values()))
        

        如果只想获取过滤器映射的键

        abc.entrySet()
               .stream()
               .filter(entry -> entry.getValue() == Collections.max(abc.values()))
               .map(Map.Entry::getKey);
        

        如果您想获取过滤后地图的值

        abc.entrySet()
              .stream()
              .filter(entry -> entry.getValue() == Collections.max(abc.values()))
              .map(Map.Entry::getvalue)
        

        如果您想在列表中获取所有此类键:

        abc.entrySet()
          .stream()
          .filter(entry -> entry.getValue() == Collections.max(abc.values()))
          .map(Map.Entry::getKey)
          .collect(Collectors.toList())
        

        如果您想在列表中获取所有此类值:

        abc.entrySet()
          .stream()
          .filter(entry -> entry.getValue() == Collections.max(abc.values()))
          .map(Map.Entry::getvalue)
          .collect(Collectors.toList())
        

        【讨论】:

          【解决方案7】:

          地图中的多数元素/最大元素:

          public class Main {
               public static void main(String[] args) {
               int[] a = {1,3,4,3,4,3,2,3,3,3,3,3};
               List<Integer> list = Arrays.stream(a).boxed().collect(Collectors.toList());
               Map<Integer, Long> map = list.parallelStream()
                       .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
               System.out.println("Map => " + map);
               //{1=1, 2=1, 3=8, 4=2}
               map.entrySet()
               .stream()
               .max(Comparator.comparing(Entry::getValue))//compare the values and get the maximum value
               .map(Entry::getKey)// get the key appearing maximum number of times
               .ifPresentOrElse(System.out::println,() -> new RuntimeException("no such thing"));
          
               /*
                * OUTPUT : Map => {1=1, 2=1, 3=8, 4=2} 
                * 3
                */
               // or in  this way 
               System.out.println(".............");
               Integer maxAppearedElement = map.entrySet()
                       .parallelStream()
                       .max(Comparator.comparing(Entry::getValue))
                       .map(Entry::getKey)
                       .get();
               System.out.println(maxAppearedElement);
          
               } 
          }
          

          【讨论】:

            【解决方案8】:
            int maxValue = 0;
            int mKey = 0;
            for(Integer key: map.keySet()){
                if(map.get(key) > maxValue){
                    maxValue = map.get(key);
                    mKey = key;
                }
            }
            System.out.println("Max Value " + maxValue + " is associated with " + mKey + " key");
            

            【讨论】:

            • 在这个论坛上,纯代码的答案通常不受欢迎。请编辑您的答案以包括对您的代码的解释。它是如何解决OP的问题的?
            【解决方案9】:

            为了完整起见,这里是 的做法

            countMap.entrySet().stream().max((entry1, entry2) -> entry1.getValue() > entry2.getValue() ? 1 : -1).get().getKey();
            

            Collections.max(countMap.entrySet(), (entry1, entry2) -> entry1.getValue() - entry2.getValue()).getKey();
            

            Collections.max(countMap.entrySet(), Comparator.comparingInt(Map.Entry::getValue)).getKey();
            

            【讨论】:

            • (entry1, entry2) -&gt; entry1.getValue() - entry2.getValue() 对于比较器来说更紧凑。
            • 如果我想要所有匹配最大值的键怎么办?
            • 紧凑但难以理解。
            • 也可以使用Integer类countMap.entrySet().stream().max((entry1, entry2) -&gt; Integer.compare(entry1.getValue(), entry2.getValue())).get().getKey();提供的比较方法
            • 或者你可以使用Map.Entry.comparingByValue()来代替
            【解决方案10】:

            我有两种方法,使用这种方法来获取具有最大值的键:

             public static Entry<String, Integer> getMaxEntry(Map<String, Integer> map){        
                Entry<String, Integer> maxEntry = null;
                Integer max = Collections.max(map.values());
            
                for(Entry<String, Integer> entry : map.entrySet()) {
                    Integer value = entry.getValue();
                    if(null != value && max == value) {
                        maxEntry = entry;
                    }
                }
                return maxEntry;
            }
            

            例如,使用以下方法获取具有最大值的条目:

              Map.Entry<String, Integer> maxEntry =  getMaxEntry(map);
            

            使用Java 8我们可以得到一个包含最大值的对象:

            Object maxEntry = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();      
            
            System.out.println("maxEntry = " + maxEntry);
            

            【讨论】:

              【解决方案11】:

              Java 8 获取具有最大值的所有键的方法。

              Integer max = PROVIDED_MAP.entrySet()
                          .stream()
                          .max((entry1, entry2) -> entry1.getValue() > entry2.getValue() ? 1 : -1)
                          .get()
                          .getValue();
              
              List listOfMax = PROVIDED_MAP.entrySet()
                          .stream()
                          .filter(entry -> entry.getValue() == max)
                          .map(Map.Entry::getKey)
                          .collect(Collectors.toList());
              
              System.out.println(listOfMax);
              

              您也可以使用parallelStream() 而不是stream() 来并行化它

              【讨论】:

                【解决方案12】:

                返回 Optional 的答案,因为如果地图为空,则地图可能没有最大值: map.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey);

                【讨论】:

                  【解决方案13】:

                  使用 Java-8 的简单单行器

                  Key key = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();
                  

                  【讨论】:

                  • @Samir,请检查您的 Java 版本。 Sleiman Jneid 明确提到它将与 Java 8 一起使用
                  • @Vaibs 我使用的是 Java 8。没关系,Hilikus 的回答对我有用。
                  • 如果有 2 个这样的最大密钥怎么办?它如何返回一个这样的键值数组?
                  • @SleimanJneidi 这个问题没有询问重复键。考虑这样的情况:- 有 2 个最大值为 8 的键。所以它应该返回 1,2。
                  【解决方案14】:

                  你可以这样做

                  HashMap<Integer,Integer> hm = new HashMap<Integer,Integer>();
                  hm.put(1,10);
                  hm.put(2,45);
                  hm.put(3,100);
                  Iterator<Integer> it = hm.keySet().iterator();
                  Integer fk = it.next();
                  Integer max = hm.get(fk);
                  while(it.hasNext()) {
                      Integer k = it.next();
                      Integer val = hm.get(k);
                      if (val > max){
                           max = val;
                           fk=k;
                      }
                  }
                  System.out.println("Max Value "+max+" is associated with "+fk+" key");
                  

                  【讨论】:

                    【解决方案15】:

                    这个解决方案好吗?

                    int[] a = { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7 };
                    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
                    for (int i : a) {
                    Integer count = map.get(i);
                    map.put(i, count != null ? count + 1 : 0);
                    }
                    Integer max = Collections.max(map.keySet());
                    System.out.println(max);
                    System.out.println(map);
                    

                    【讨论】:

                      【解决方案16】:

                      对于我的项目,我使用了 Jon 和 Fathah 解决方案的略微修改版本。在多个条目具有相同值的情况下,它返回它找到的最后一个条目:

                      public static Entry<String, Integer> getMaxEntry(Map<String, Integer> map) {        
                          Entry<String, Integer> maxEntry = null;
                          Integer max = Collections.max(map.values());
                      
                          for(Entry<String, Integer> entry : map.entrySet()) {
                              Integer value = entry.getValue();
                      
                              if(null != value && max == value) {
                                  maxEntry = entry;
                              }
                          }
                      
                          return maxEntry;
                      }
                      

                      【讨论】:

                        【解决方案17】:

                        下面是如何通过定义适当的Comparator 来直接(没有显式的额外循环):

                        int keyOfMaxValue = Collections.max(
                                                yourMap.entrySet(), 
                                                new Comparator<Entry<Double,Integer>>(){
                                                    @Override
                                                    public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
                                                        return o1.getValue() > o2.getValue()? 1:-1;
                                                    }
                                                }).getKey();
                        

                        【讨论】:

                          【解决方案18】:

                          基本上,您需要遍历地图的条目集,同时记住“当前已知的最大值”和与之关联的键。 (当然,或者只是包含两者的条目。)

                          例如:

                          Map.Entry<Foo, Bar> maxEntry = null;
                          
                          for (Map.Entry<Foo, Bar> entry : map.entrySet())
                          {
                              if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0)
                              {
                                  maxEntry = entry;
                              }
                          }
                          

                          【讨论】:

                          • +1:您可以拥有多个具有相同最大值的键。这个循环会给你它找到的第一个。
                          • 将 > 0 更改为 >= 0 将为您提供它找到的最后一个
                          • Java 8 流的使用是否有助于简化这一点?例如:map.forEach((k,v) -> ...
                          • @zkarthik:将max 与自定义比较器一起使用可能会更简单。
                          猜你喜欢
                          • 1970-01-01
                          • 2016-01-28
                          • 1970-01-01
                          • 2012-11-03
                          • 2010-12-07
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2021-12-30
                          相关资源
                          最近更新 更多