I am looking for a Java equivalent for python snippet
max_valued_key = max(str_to_double_map.keys(), key=lambda x: str_to_double_map[x])
I want to something standard like Collections.max
Is there a way to do this with inline definition of Comparator since I don't want to write one more class for every other comparator.
I tried following code unsuccessfully
depScores = foo();
String dep = Collections.max(depScores.keySet(), new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return depScores.get(o1).compareTo(depScores.get(o2));
}
});
depScores variable is not readable from comparator.
Looks like in java inner class cannot access non-final variable from outside!
Thanks in advance!
Just declare depScores
as a final variable. If for some reason you can't, create a second (final) variable that points to it.
Local classes can capture variables only if they are final.
As a (very) late addendum, it is trivial to create a custom Comparator
from a lambda in Java 8:
String dep = Collections.max(
depScores.keySet(),
Comparator.comparing(k -> depScores.get(k))
);
You can get even more terse by replacing the lambda k -> depScores.get(k)
with the method reference depScores::get
.
The rules for capturing local variables like depScore
are a little more flexible for lambdas than inner classes: captured variables need only be effectively final. In other words, they must be assigned exactly once, though they needn't be explicitly marked final
.
What you want is (will be) possible with Java 8:
Map<String,Double> map…
String maxKey=Collections.max(map.keySet(), (x,y)->Double.compare(map.get(x),map.get(y)));
or even shorter
String maxKey = Collections.max(map.keySet(), Comparator.comparingDouble(map::get));
For previous Java version you have to use:
String maxKey=Collections.max(map.keySet(), new Comparator<String>(){
public int compare(String x, String y) {
return Double.compare(map.get(x),map.get(y));
}
});
Problems with map
not being final
can be circumvented by assigning it to a final variable right before the invocation:
final Map<String,Double> fmap=map;
String maxKey=Collections.max(map.keySet(), new Comparator<String>(){
public int compare(String x, String y) {
return Double.compare(fmap.get(x),fmap.get(y));
}
});
But I think even more straightforward and more efficient will be the following helper method as it does not require any hash lookups:
static <K,V extends Comparable<V>> K keyForHighestValue(Map<K,V> map) {
V maxValue=Collections.max(map.values());
for(Map.Entry<K,V> e:map.entrySet()) {
if(e.getValue()==maxValue) return e.getKey();
}
throw new ConcurrentModificationException();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With