Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort Map in Ascending Order by Key

I'm attempting to sort a Map in ascending order based on the keys. Given the Map:

Map<Integer, String> map = new LinkedHashMap<Integer, String>();

map.put(5, "five");
map.put(1, "one");
map.put(3, "three");
map.put(0, "zero");

I would like the order:

0, zero
1, one
3, three
5, five

I wrote the following code to accomplish this:

    public <K, V extends Comparable<? super V>> Map<K, V> sortByKeyInAscendingOrder(Map<K, V> map)
{
    List<Entry<K, V>> list = new ArrayList<>(map.entrySet());
    list.sort(Entry.comparingByKey());

    Map<K, V> result = new LinkedHashMap<>();
    for (Entry<K, V> entry : list) {
        result.put(entry.getKey(), entry.getValue());
    }
    return result;
}

However, when I call sort() I get the following error:

The method sort(Comparator<? super Map.Entry<K,V>>) in the type List<Map.Entry<K,V>> is not applicable for the arguments (Comparator<Map.Entry<Comparable<? super Comparable<? super K>>,Object>>)

I've written similar code (which works fine) to sort by value (changing Entry.comparingByKey() to Entry.comparingByValue() ) but for some reason when I try sorting by key I get the above error.

How can I fix this?

Thanks

like image 822
Alan Cook Avatar asked Jan 26 '23 20:01

Alan Cook


2 Answers

You'd need to make K comparable to sort by it; and the bound on V is wrong (but unnecessary anyway).

public <K extends Comparable<? super K>, V> Map<K, V> sortByKeyInAscendingOrder(Map<K, V> map)

Mind you, an easier way might be:

return new LinkedHashMap<>(new TreeMap<>(map));

Or

return map.entrySet().stream()
    .sorted(Entry.comparingKey())
    .collect(toMap(k -> k, v -> v, LinkedHashMap::new));
like image 93
Andy Turner Avatar answered Jan 31 '23 20:01

Andy Turner


The method comparingByKey requires its key, K type parameter, to be Comparable, not (necessarily) its value, V.

Move the bound ? extends Comparable<? super K> from V to K. Change

<K, V extends Comparable<? super K>>

to

<K extends Comparable<? super K>, V>

It is of course optional to have V be Comparable also, but make that bound refer to itself, not to K:

V extends Comparable<? super V>
like image 34
rgettman Avatar answered Jan 31 '23 19:01

rgettman