2
Stream<Map.Entry<String, List<Object>>> sorted = index.entrySet().stream()
                .sorted(Map.Entry.comparingByValue());

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

I want to sort a Hashmap according to the size() of Lists being the values of the HashMap. How can I achieve this using the Stream library from Java 8?

skaffman
  • 398,947
  • 96
  • 818
  • 769
Pete
  • 502
  • 1
  • 6
  • 20
  • I copied the code from that post, but I don't know how to access the size() parameter of the List values in this case since comparingByValue seems to work on primitive data types and Strings only(?) – Pete Apr 29 '15 at 07:19
  • Are you trying to sort map entries by size of lists (which are entry's value)? – Karol Król Apr 29 '15 at 07:23

3 Answers3

5

This may be helpful to you.

I changed the type of result map to LinkedHashMap to respect insertion order.

public static void main(String[] args) {
    final Map<String, List<Integer>> map = new HashMap<>();
    map.put("k1", Arrays.asList(new Integer[]{1, 2, 3, 4, 5}));
    map.put("k2", Arrays.asList(new Integer[]{1, 2, 3, 4, 5, 6}));
    map.put("k3", Arrays.asList(new Integer[]{1, 2, 3}));
    System.out.println(getMapSortedByListSize(map));
}

public static <K, V> Map<K, List<V>> getMapSortedByListSize(final Map<K, List<V>> map) {
    return map.entrySet().stream()
            .sorted((e1, e2) -> e1.getValue().size() - e2.getValue().size())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, LinkedHashMap::new));
}
Karol Król
  • 3,320
  • 1
  • 34
  • 37
3

Map.Entry.comparingByValue() will only work if the values in the map are Comparable, and List is not Comparable. The error from the compiler is telling you that.

You need to provide a custom Comparator which knows how to sort lists by their size, e.g.

Map.Entry.comparingByValue((list1, list2) -> list1.size() - list2.size())
skaffman
  • 398,947
  • 96
  • 818
  • 769
0

Map.Entry.comparingByValue() cannot serve as the comparator.

This is a comparator for Stream<T> sorted(Comparator<? super T> comparator):

Stream<Entry<String, List<Object>>> sortedStream = index.entrySet().stream()
        .sorted(new Comparator<Map.Entry<String,List<Object>>>() {
    @Override
    public int compare(Entry<String, List<Object>> o1, Entry<String, List<Object>> o2) {
        return o1.getValue().size()-o2.getValue().size();
    }
});
cshu
  • 5,654
  • 28
  • 44
  • 1
    `Map.Entry.comparingByValue() ` can serve as a comparator if the values of the map are comparable. This is not the case for List and hence the compile error. If not you can just provide one to the overloaded method (and it avoids to provide a comparator for the entries instead since you are interested to compare the entries only with their respective values)... Furthermore, your code could be simplified with lambda expressions here – Alexis C. Apr 29 '15 at 08:07