Reputation: 362
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
Upvotes: 5
Views: 3824
Reputation: 39998
You can also try using java 8 streams
Map<Integer, String> map = new LinkedHashMap<Integer, String>();
map.put(5, "five");
map.put(1, "one");
map.put(3, "three");
map.put(0, "zero");
map = map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(map); //{0=zero, 1=one, 3=three, 5=five}
Or you can use forEach
on Map
map.forEach((k,v)->System.out.println(k+" "+v));
Upvotes: 3
Reputation: 140309
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));
Upvotes: 4
Reputation: 846
How about using a TreeMap? it keeps keys sorted in natural order:
https://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html
If you need to create it from an existing map, use it's parameterized constructor:
TreeMap<Integer,String> treeMap = new TreeMap<>(map);
because using a HashMap doesn't guarantee order and LinkedHashMap maintains insertion order. To keep map sorted by key, use TreeMap.
Upvotes: 2
Reputation: 178253
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>
Upvotes: 2