Finding Key Associated with Max Value in a Java Map

Finding Key associated with max Value in a Java Map

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

Get the highest values in a hashmap in java

The first step is to find the highest value at all.

int max = Collections.max(map.values());

Now iterate through all the entries of the map and add to the list keys associated with the highest value.

List<String> keys = new ArrayList<>();
for (Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue()==max) {
keys.add(entry.getKey());
}
}

If you like the Java 8 Stream API, try the following:

map.entrySet().stream()
.filter(entry -> entry.getValue() == max)
.map(entry -> entry.getKey())
.collect(Collectors.toList());

How to get a Key from HashMap which corresponds to the max value?

I used TreeMap instead of HashMap so that I can sort the map if needed (maybe not need).

For that purpose, HashMap will suffice, you might replace TreeMap with a HashMap if you are not utilizing it for anything else. And moreover, TreeMap can't help with this task because maintains the order of entries based on keys, not on values (your example is slightly misleading - max value is mapped to a max key, if you change it, TreeMap will no longer be helpful).

To solve this problem with Stream API, firstly, you need to create a stream over the entry set, because you can't access a key when you have only a value.

Terminal operation max() returns an optional object that will hold entry (if result is present). Method map() invoked on an optional will transform Optional<Map.Entry<Integer, Integer>> into Optional<Integer>.

Method orElseThrow() in this case will be a better alternative to get(). Both will throw an exception if optional object will be empty. If according to your logic, value is guaranteed to be present it better specify explicitly with orElseThrow() that your intention is to throw an exception when result is not present, because this case is abnormal.

NavigableMap<Integer, Integer> map = new TreeMap<>();

int maxKey = map.entrySet().stream()
.max(Map.Entry.comparingByValue()) // Optional<Map.Entry<Integer, Integer>> - entry
.map(Map.Entry::getKey) // Optional<Integer> - key
.orElseThrow();

Since multiple keys could have the same value, it is possible that max value will be mapped to more than one key. In this case you might want to get a list of these keys:

NavigableMap<Integer, Integer> map = new TreeMap<>();

int maxValue = map.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getValue)
.orElseThrow();

List<Integer> maxValues = map.entrySet().stream()
.filter(entry -> entry.getValue() == maxValue)
.map(Map.Entry::getKey)
.collect(Collectors.toList());

Sidenote: when you are working with a TreeMap and don't expect that variable could be assigned with an unsorted implementation of the interface Map, then use interface NavigableMap as a type. It'll provide you access to such methods as getFirstEntry(), getFirstKey(), higherEntry(), etc. that will not be available with Map.

Finding the key corresponding to the maximum value in a hash map

You are attempting to pass a lambda that should implement Comparable as an argument to max, but Comparable must return an int, while you are producing a double as the result of subtracting a double from another.

You can fix this easily by using Double.compare(e1.getValue(), e2.getValue()) instead of subtracting both values:

 Node bestNode = Collections.max(coinD.entrySet(), 
(e1, e2) -> Double.compare(e1.getValue(), e2.getValue())).getKey();

@ernest_k also has a good point: if the values of your map are have a natural sort order, and you want to use that order, Map.Entry.comparingByValue yields slightly shorter code:

 Node bestNode = Collections.max(coinD.entrySet(), 
(e1, e2) -> Map.Entry.comparingByValue()).getKey();

Find a String key associated with the Max Integer value in a MapString, Integer

You can do it like this. Stream entrySet of the map and then get the maximum entry by using maxBy on the value of the entry. Since maxBy returns an Optional, you can then use map to get the value. Return an informatory message if no value exists.

 String result  = wordFreq.entrySet().stream()
.collect(Collectors.maxBy(Entry.comparingByValue()))
.map(Entry::getKey).orElse("No Value Found");

And as was commented on you could also do this. I tend to use the first one out of habit.

String result = wordFreq.entrySet().stream()         
.max(Entry.comparingByValue())
.map(Entry::getKey).orElse("No Value Found");

You could also use other ways to optimize this but since you constructed a map I figured that is how you wanted to do it.
If you need a map of words, you may want to construct it outside of the method. Then just pass the map to the method instead of an array of sentences. That way you can use the map for other things.

Since you haven't yet had a chance to respond to my question, I will offer a solution regarding ties for the maximum occurrence of a word. Similar as before except first you return the maximum value found. The you can stream the entrySet, filtering for the entries that have the maximum value. Then just collect into a list.


int max = wordFreq.entrySet().stream()
.max(Entry.comparingByValue()).map(Entry::getValue)
.orElse(0);

List<String> wordFreq.entrySet().stream()
.filter(e -> e.getValue() == max).map(Entry::getKey)
.toList();

}

Lastly, you use stream constructs to create the initial frequency map. I am using \\s+ as the regex as there could be more than one space. The splitAsStream will apply the pattern and the toMap is similar to a merge in functionality.

Map<String, Integer> wordFreq = Arrays.stream(sentences)
.flatMap(s -> Pattern.compile("\\s+").splitAsStream(s))
.collect(Collectors.toMap(x -> x, x -> 1,
Integer::sum));

Get the key for the maximum value in a HashMap using Collections

Just iterate the entry set looking for the largest value:

Map.Entry<MyObject, Double> maxEntry = null;
for (Map.Entry<MyObject, Double> entry : map.entrySet()) {
if (maxEntry == null || entry.getValue() > maxEntry.getValue()) {
maxEntry = entry;
}
}
MyObject maxKey = maxEntry.getKey(); // Might NPE if map is empty.

or, if you want to get all keys with maximal value:

double maxValue = null;
List<MyObject> maxKeys = new ArrayList<>();
for (Map.Entry<MyObject, Double> entry : map.entrySet()) {
if (maxValue == null || maxValue.equals(entry.getValue())) {
maxValue = entry.getValue();
maxKeys.add(entry.getKey());
} else if (entry.getValue() > maxValue) {
maxValue = entry.getValue();
maxKeys.clear();
maxKeys.add(entry.getKey());
}
}

How to return key associated to highest value in nested map (Java)?

Given

Given your map with

singer_map: interpret -> title_map
title_map: title -> rating

like:

Map<String, HashMap<String, Integer>> singers = new HashMap<>();
singers.put("Elvis", new HashMap<>());
singers.get("Elvis").put("All Shook up", 8);
singers.get("Elvis").put("Don't be Cruel", 5);
singers.get("Elvis").put("Viva las Vegas", 3);

Algorithm

Now define a temporary entry variable for the favoriteTitle.
Take the title-map like Map<String, Integer> titles = singers.get("Elvis") and iterate over each entry (e.g. a for-each loop).

In the loop-body of each iteration:
If an entry is higher then favoriteTitle or favoriteTitle is empty, then store the current entry.

After the loop you have the favoriteTitle with highest rating for this singer. If the singer has no titles, then there is also no favorite.

What if all or the more than 1 highest rated titles have the same rating?

Sample code

Map<String, Integer> titles = singers.get("Elvis");
Map.Entry<String, Integer> favoriteTitle;

for (Map.Entry<String, Integer> t : titles) {
System.out.println(t.getKey() + " rated " + t.getValue());
if (favoriteTitle == null || favoriteTitle.getValue() < t.getValue()) {
favoriteTitle = t;
}
}
System.out.println("Favorite: " + favoriteTitle.getKey() + " rated " + favoriteTitle.getValue());

See also:

  • GeeksforGeeks: Map.Entry interface in Java with example, tutorial

How to get the id of the highest value element in a treemap

We can get the entrySet() from the TreeMap and stream on it, then find the max value from the set of entries by comparing the values of each entries and getting the key from the entry having the highest value.

map.entrySet().stream()
.max(Map.Entry.comparingByValue()))
.ifPresent(e -> System.out.println(e.getKey()));

How do I find the keys associated with the maximum value in HashMap?

What you can do here is just sort your HashMap and pick the first or last keys to get max or min values.

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

Remember -Their may be more then one keys with same value.

Print the Key for the N-th highest Value in a HashMap

Here is one way. It is presumed by Nth highest that duplicates must be ignored. Otherwise you would be asking about position in the map and not the intrinsic value as compared to others. For example, if the values are 8,8,8,7,7,5,5,3,2,1 then the 3rd highest value is 5 where the value 8 would be simply be value in the 3rd location of a descending sorted list.

  • initialize found to false and max to Integer.MAX_VALUE.
  • sort the list in reverse order based on value. Since the TreeMap is already sorted by keys and is a stable sort (see Sorting algorithms) the keys will remain in sorted order for duplicate values.
  • loop thru the list and continue checking if the current value is less than max. The key here is less than, That is what ignores the duplicates when iterating thru the list.
  • if the current value is less than max, assign to max and decrement n. Also assign the key
  • if n == 0, set found to true and break out of the loop.
  • if the loop finishes on its own, found will be false and no nth largest exists.
Map<String, Integer> map = new TreeMap<>(Map.of(
"peter" , 40, "mike" , 90, "sam",60, "john",90, "jimmy" , 32, "Alex",60,"joan", 20, "alice", 40));

List<Entry<String,Integer>> save = new ArrayList<>(map.entrySet());

save.sort(Entry.comparingByValue(Comparator.reverseOrder()));

int max = Integer.MAX_VALUE;
boolean found = false;
String key = null;
for (Entry<String,Integer> e : save) {
if (e.getValue() < max) {
max = e.getValue();
key = e.getKey();
if (--n == 0) {
found = true;
break;
}
}
}

if (found) {
System.out.println("Value = " + max);
System.out.println("Key = " + key);
} else {
System.out.println("Not found");
}

prints

Value = 60
Key = Alex




Related Topics



Leave a reply



Submit