Ben B.
Ben B.

Reputation: 3826

Finding Key associated with max Value in a Java Map

What is the easiest way to get key associated with the max value in a map?

I believe that Collections.max(someMap) will return the max Key, when you want the key that corresponds to the max value.

Upvotes: 191

Views: 423156

Answers (20)

Jorgesys
Jorgesys

Reputation: 126455

I have two methods, using this méthod to get the key with the max value:

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

As an example gettin the Entry with the max value using the method:

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

Using Java 8 we can get an object containing the max value:

Object maxEntry = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();      

System.out.println("maxEntry = " + maxEntry);

Upvotes: 7

Jon Skeet
Jon Skeet

Reputation: 1500185

Basically you'd need to iterate over the map's entry set, remembering both the "currently known maximum" and the key associated with it. (Or just the entry containing both, of course.)

For example:

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

Upvotes: 160

Hilikus
Hilikus

Reputation: 10331

For completeness, here is a way of doing it

Cleanest way:

Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey()

or

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

or

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

or

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

Upvotes: 187

Imran Sefat
Imran Sefat

Reputation: 773

    int max = 0;
// here m is a HashMap<String, Integer>
    for(Map.Entry<String,Integer> entry : m.entrySet()){

       if(entry.getValue() > max){
          max = entry.getValue();              
       }
    }

Upvotes: 1

Dr.jacky
Dr.jacky

Reputation: 3547

Kotlin:

val key = map.toList().groupingBy { it }.eachCount().maxByOrNull { it.value }?.key

Upvotes: 0

Sophie
Sophie

Reputation: 77

The simplest way is:

Collections.max(hmap.values());

Upvotes: -2

Manas Ranjan Mahapatra
Manas Ranjan Mahapatra

Reputation: 423

1. Using Stream

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. Using Collections.max() with a Lambda Expression

    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. Using Stream with Method Reference

    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. Using 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. Using Simple Iteration

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

Upvotes: 11

Fathah Rehman P
Fathah Rehman P

Reputation: 8741

This code will print all the keys with maximum value

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

    }
}

Upvotes: 71

goedi
goedi

Reputation: 2083

This is going to return the keys with max value in a Map<Integer, Integer>

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

Upvotes: 0

NickyPatel
NickyPatel

Reputation: 555

Simple to understand. In Below code, maxKey is the key which is holding the max value.

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

Upvotes: 7

Arpan Saini
Arpan Saini

Reputation: 5181

given map

HashMap abc = new HashMap<>();

get all map entries with a maximum of values.

you can use any of the below methods in the filter to get respective map entries for sets of minimum or maximum values

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()))

if only want to get the keys for the filter map

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

if you want to get the values for the filtered map

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

if you want to get all such keys in a list:

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

if you want to get all such values in a list:

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

Upvotes: 4

Soudipta Dutta
Soudipta Dutta

Reputation: 2122

Majority Element/ max element in the map :

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

     } 
}

Upvotes: 1

Abdullah Uzundere
Abdullah Uzundere

Reputation: 11

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");

Upvotes: 1

Mariusz Szurgot
Mariusz Szurgot

Reputation: 432

Java 8 way to get all keys with max value.

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

Also you can parallelize it by using parallelStream() instead of stream()

Upvotes: 4

David L
David L

Reputation: 44657

An answer that returns an Optional since the map may have no max value if it is empty: map.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey);

Upvotes: 7

Sleiman Jneidi
Sleiman Jneidi

Reputation: 23329

A simple one liner using Java-8

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

Upvotes: 82

Parnab Sanyal
Parnab Sanyal

Reputation: 739

you can do like that

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");

Upvotes: -1

Danilo
Danilo

Reputation: 319

Is this solution ok?

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

Upvotes: 1

k_rollo
k_rollo

Reputation: 5472

For my project, I used a slightly modified version of Jon's and Fathah's solution. In the case of multiple entries with the same value, it returns the last entry it finds:

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

Upvotes: 0

Amir
Amir

Reputation: 898

Here's how do do it directly (without an explicit extra loop) by defining the appropriate 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();

Upvotes: 10

Related Questions