3

I have a map:

private Map<String, AtomicInteger> keywordMap = new HashMap<String, AtomicInteger>();

I'm trying to sort the Map by value (AtomicInteger), in Java 8, with the following code:

keywordMap
        .entrySet()
        .parallelStream()
        .sorted().forEachOrdered(e -> System.out.print(e.getKey()));

However, I'm getting the following error:

java.lang.ClassCastException: java.util.HashMap$Node cannot be cast to java.lang.Comparable

The error occurs in this line: .forEachOrdered(e -> System.out.print(e.getKey()));

What is wrong with my code?

Vlad
  • 18,195
  • 4
  • 41
  • 71
Namjug
  • 153
  • 1
  • 10

2 Answers2

7

Try to use:

Stream<Map.Entry<K,V>> keywordMap = keywordMap.entrySet().stream().sorted(Map.Entry.comparingByValue());
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
4

The problem is that you try to use sorted() to sort a stream of Map.Entry instances. Map.Entry does not implement the Comparable interface, and that's why you get the ClassCastException. So you will have to supply a suitable comparator yourself.

Also, AtomicInteger does not implement Comparable, and that is why you cannot use Map.Entry.comparingByValue(). You really have to write your own comparator:

keywordMap.entrySet()
    .parallelStream()
    .sorted((a,b) -> Integer.compare(a.getValue().get(), b.getValue().get())); 

However, AtomicInteger does not implement Comparable for a reason. Typically, AtomicIntegers are accessed by multiple threads and thus they can change during the sorting, which might lead to undesirable results (exceptions, even).

Hoopje
  • 12,677
  • 8
  • 34
  • 50