Reputation: 3826
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
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
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
Reputation: 10331
For completeness, here is a java-8 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
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
Reputation: 3547
Kotlin:
val key = map.toList().groupingBy { it }.eachCount().maxByOrNull { it.value }?.key
Upvotes: 0
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
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
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
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
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
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
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
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
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
Reputation: 23329
A simple one liner using Java-8
Key key = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();
Upvotes: 82
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
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
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
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