Java 使用 Collections.reverseOrder() 按值降序排列 TreeMap

Java order TreeMap by value descending using Collections.reverseOrder()

我想按降序对现有 TreeMap 进行排序(或将值从 Map 复制到 TreeMap,这无关紧要),按值(双精度)排序。

我知道这里有很多类似的问题,但是据我所知,在 Java8 中,您可以在不创建自己的比较器的情况下完成此操作,而是使用 Collections.reverseOrder。

某处有一个答案准确描述了这一点。基于它,我尝试实现它:

private Map<String, Double> orderByDescValue(Map<String, Double> unorderedMap) {
    Stream<Map.Entry<String,Double>> sorted = unorderedMap.entrySet().stream()
            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
    return sorted.limit(Configuration.WORDCLOUD_SIZE)
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

}

我知道这是行不通的,因为它 returns 是一个不声明任何顺序的地图,而不是 TreeMap。但是 Collectors 似乎没有 toTreeMap,我无法投射它 - 我不知道还能做什么。

或者也许它不能这样工作,我必须用另一种方式解决这个问题?

您可以利用 LinkedHashMap 将保留广告订单这一事实 - 因此在 toMap 调用中指定供应商,以便它会适当地创建 LinkedHashMap

.collect(Collectors.toMap(
    Map.Entry::getKey,
    Map.Entry::getValue,
    (x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
    LinkedHashMap::new));

那不会是 TreeMap,但您的方法没有声明它 returns 是 TreeMap,只是 Map。如果你真的、真的需要一个 TreeMap,我建议你更改签名 - 但那会很奇怪,因为 TreeMap 按键而不是按值排序。

完整示例:

import java.util.*;
import java.util.stream.*;

public class Test {
    public static void main(String[] args) throws Exception {
        Map<String, Double> unordered = new HashMap<>();
        unordered.put("a", 10.5);
        unordered.put("b", 5.3);
        unordered.put("c", 12.7);
        unordered.put("d", 6.0);

        Map<String, Double> ordered = orderByDescValue(unordered);
        for (Map.Entry<String, Double> entry : ordered.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    private static Map<String, Double> orderByDescValue(Map<String, Double> unorderedMap) {
        return unorderedMap.entrySet().stream()
            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
                LinkedHashMap::new));
    }
}

输出:

c: 12.7
a: 10.5
d: 6.0
b: 5.3

此外,您无需将方法限制为仅处理该类型的地图 - 您可以将其设为通用:

private static <K, V extends Comparable<V>> Map<K, V> orderByDescValue(Map<K, V> unorderedMap) {
    return unorderedMap.entrySet().stream()
        .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
        .collect(Collectors.toMap(
            Map.Entry::getKey,
            Map.Entry::getValue,
            (x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
            LinkedHashMap::new));
}

(我确定我可以添加一堆 ? extends K 或其他任何内容,但我现在将其保留为更简单的形式...)