3

I'm trying to sort a java.util.Map as follows.

public final class SortMapByValue <K, V extends Comparable<? super V>> implements Comparator<Map.Entry<K, V>>
{
 @Override
 public int compare(Entry<K, V> o1, Entry<K, V> o2) {
 return (o1.getValue()).compareTo(o2.getValue());
 }
 public static <K, V extends Comparable<? super V>> Map<K, V> sortMapByValue(Map<K, V> unsortedMap)
 {
 List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(unsortedMap.entrySet()); 
 Collections.sort(list); //Compiler error here.
 Map<K, V> sortedMap = new LinkedHashMap<K, V>();
 for (Map.Entry<K, V> entry : list) {
 sortedMap.put(entry.getKey(), entry.getValue());
 }
 return sortedMap;
 }
}

As commented in the code, it issues a compile-time error as follows.

no suitable method found for sort(List<Entry<K,V>>)
 method Collections.<T#1>sort(List<T#1>,Comparator<? super T#1>) is not applicable
 (cannot instantiate from arguments because actual and formal argument lists differ in length)
 method Collections.<T#2>sort(List<T#2>) is not applicable
 (inferred type does not conform to declared bound(s)
 inferred: Entry<K,V>
 bound(s): Comparable<? super Entry<K,V>>)
 where K,V,T#1,T#2 are type-variables:
 K extends Object declared in method <K,V>sortMapByValue(Map<K,V>)
 V extends Comparable<? super V> declared in method <K,V>sortMapByValue(Map<K,V>)
 T#1 extends Object declared in method <T#1>sort(List<T#1>,Comparator<? super T#1>)
 T#2 extends Comparable<? super T#2> declared in method <T#2>sort(List<T#2>)

This could also be done in the following way in the sortMapByValue() method as follows.

Collections.sort(list, new Comparator<Map.Entry<K, V>>()
{
 @Override
 public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
 return (o1.getValue()).compareTo(o2.getValue());
 }
});

But instead, I would like fixing the the error to follow that way (avoiding this anonymous comparator). How to fix that error?

asked Mar 2, 2014 at 19:14
5
  • 3
    You have a List of Entry's. The class Entry does not implement Comparable. However, Collections.sort(..) expects a List of some type that implements Comparable. Commented Mar 2, 2014 at 19:17
  • So you have code that doesn't compile, and code that works perfectly. The problem with the code that works is that you want to use the code that doesn't compile, and the problem with the code that doesn't compile is that you want it to compile. Do I have that right? Commented Mar 2, 2014 at 19:19
  • You need to pass the comparator to Collections.sort, for example like Collections.sort(list, new SortMapByValue()); Commented Mar 2, 2014 at 19:19
  • possible duplicate of How to sort a Map<Key, Value> on the values in Java? Commented Mar 2, 2014 at 19:50
  • Liable to be closed as unclear what you're asking, really? :) Commented Mar 10, 2014 at 5:32

1 Answer 1

8

Map.Entry does not implement Comparable, so Collections.sort(List<Entry>) has no way to know how the entries should be sorted. So you have to provide a Comparator.

But since your SortMapByValue already implements the Comparator interface, you can simply use an instance of that class:

Collections.sort(list, new SortMapByValue<>());

Also note that with Java 8 you can significantly reduce the length of the code:

public static <K, V extends Comparable<? super V>> Map<K, V> sortMapByValue(Map<K, V> unsortedMap) {
 return unsortedMap.entrySet().stream()
 .sorted(comparing(Entry::getValue))
 .collect(toMap(Entry::getKey, Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));
}
answered Mar 2, 2014 at 19:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.