Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get max key of Map<K,V> using lambda

I have a Map<Float, String> and would like to get the maximum of all keys. In C# I would do something like this:

var dictionary = new Dictionary<float, string>{{5,"foo"}, {42, "bar"}, {0, "foobarz"}};
float max = dictionary.Max(x => x.Key); //42

Now I'm looking for a way to do the same using Java 8 lambdas, but the closest I got is:

float max = (float)map.keySet().stream().mapToDouble((x) -> x).summaryStatistics().getMax();

This looks awful and requires completely unnecessary type casts. Is there a better way to do this?

like image 207
Jay Avatar asked May 23 '14 15:05

Jay


2 Answers

The interface Stream contains the method max to get the maximum element. You can use a method reference as Comparator. The method max returns an Optional<Float>, because there is no maximum element in an empty stream. You can use the method orElse to provide an alternative value for this case.

float max = map.keySet().stream().max(Float::compareTo).orElse(0.0f);
like image 99
nosid Avatar answered Sep 21 '22 03:09

nosid


There's a more direct solution than operating on the keySet(); operate directly on the entrySet() using the comparator factories added to Map.Entry.

Map.Entry<K,V> maxElt = map.entrySet().stream()
                           .max(Map.Entry.comparingByKey())
                           .orElse(...);

This permits not only getting min/max elements, but also sorting, so its easy to find the top ten key/value pairs like this:

Stream<Map.Entry<K,V>> topTen = map.entrySet().stream()
                                   .sorted(Map.Entry.byKeyComparator().reversed())
                                   .limit(10);
like image 37
Brian Goetz Avatar answered Sep 23 '22 03:09

Brian Goetz