简体   繁体   中英

How to sort a HashMap by value but keep the order of duplicates?

I'm trying to sort the tableProbability map into a new one called sorted . In tableProbability the values are the following:

Key Value
M 0.1
U 0.3
L 0.3
T 0.2
I 0.1

I have the following code that sorts the Map :

LinkedHashMap<Character, Double> sorted = new LinkedHashMap<>();
tableProbability.entrySet()
        .stream()
        .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
        .forEachOrdered(x -> sorted.put(x.getKey(), x.getValue()));

But what I end up getting is the following Map :

Key Value
L 0.3
U 0.3
T 0.2
I 0.1
M 0.1

And what I am supposed to get is:

Key Value
U 0.3
L 0.3
T 0.2
M 0.1
I 0.1

Is there any way to retain the duplicate order or at least when it finds a duplicate to put it past the one with the equal value?

Your code works fine, but you can simplify it as follows:

  1. Source map:

     LinkedHashMap<Character, Double> tableProbability = new LinkedHashMap<>() {{ put('M', 0.1); put('U', 0.3); put('L', 0.3); put('T', 0.2); put('I', 0.1); }};
     System.out.println(tableProbability); // {M=0.1, U=0.3, L=0.3, T=0.2, I=0.1}
  2. This code works fine:

     LinkedHashMap<Character, Double> sorted = new LinkedHashMap<>(); tableProbability.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).forEachOrdered(x -> sorted.put(x.getKey(), x.getValue()));
     System.out.println(sorted); // {U=0.3, L=0.3, T=0.2, M=0.1, I=0.1}
  3. Simplified version:

     LinkedHashMap<Character, Double> sorted2 = tableProbability.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(LinkedHashMap::new, (col, e) -> col.put(e.getKey(), e.getValue()), HashMap::putAll);
     System.out.println(sorted2); // {U=0.3, L=0.3, T=0.2, M=0.1, I=0.1}

See also: Ordering Map<String, Integer> by List<String> using streams

You may want to do it this way. It is common operation. If you want to return a TreeMap , you can specify it below. And normally one assigns to the interface type. For a TreeMap it would be NavigableMap .

Map<Character, Double> sorted =
        tableProbability.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(
                        Comparator.reverseOrder()))
                .collect(Collectors.toMap(Entry::getKey,
                        Entry::getValue,
                        (a,b)->a, // merge, not used here but
                                  // syntactically required
                        LinkedHashMap::new // type of map to return
                        ));

Use a compound comparator:

.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())
    .andThen(Map.Entry.comparingByKey())
)
    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM