1

I have a HashMap which I try to sort by its values (largest to smallest). I want a new Map object which is a clone of the new sorted hash map (or a way to directly sort the hashmap itself). Here is my following code:

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class Repetition {
    public static Map<Object, Integer> countRepititions(Object[] e) {
        Map<Object, Integer> occurrences = new HashMap<>();
        for (int i = 0; i < e.length; i++) {
            occurrences.putIfAbsent(e[i], 0);
            occurrences.computeIfPresent(e[i], (k, v) -> v + 1);
        }

        return occurrences.entrySet().stream()
                                     .sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
                                     .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, HashMap::new));
    }

    public static void main(String[] args) {
        Object[] arr = { "cat", "dog", "cat", "cow", "cow", "cow" };

        System.out.println(countRepititions(arr)); //should be cow, cat, dog
    }
}

The issue is that the output is that of the original hashmap rather than the sorted hash map. If anyone could help me, it would be greatly appreciated!

EDIT: I managed to modify the current code by using a LinkedHashMap instead.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183

1 Answers1

3

You want to use LinkedHashMap that preserves order (suitable for sorting). The solution requires two streams:

public static Map<Object, Long> countRepititions(Object[] e) {
  return Arrays.stream(e)
      .collect(Collectors.groupingBy(
              Function.identity(),                                   // object as key
              Collectors.counting()))                                // count is value
      .entrySet().stream()
      .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) // reversed order
      .collect(Collectors.toMap(
              Map.Entry::getKey,                                     // preserve keys
              Map.Entry::getValue,                                   // preserve values
              (l, r) -> l,                                           // merge function
              LinkedHashMap::new));                                  // LinkedHashMap
}

Printing out such returned map results in:

{cow=3, cat=2, dog=1}

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183