如何按值对 HashMap 进行排序但保持重复项的顺序?

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

我正在尝试将 tableProbability 地图分类为一个名为 sorted 的新地图。在 tableProbability 中,值如下:

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

我有以下代码对 Map 进行排序:

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

但我最终得到的是以下 Map:

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

而我应该得到的是:

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

有没有办法保留重复的订单,或者至少在找到重复订单时将其放在具有相同价值的订单之后?

你可能想这样做。是普通操作。如果你想return一个TreeMap,你可以在下面指定。通常一个分配给接口类型。对于 TreeMap 它将是 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
                        ));

您的代码工作正常,但您可以按如下方式简化它:

  1. 源图:

    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. 这段代码工作正常:

    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. 简化版:

    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}
    

另请参阅:

使用复合比较器:

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