【问题标题】:Java order TreeMap by value descending using Collections.reverseOrder()Java 使用 Collections.reverseOrder() 按值降序排列 TreeMap
【发布时间】:2015-12-10 13:44:33
【问题描述】:

我想以降序对现有 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));

}

我知道这不起作用,因为它返回一个不断言任何顺序的 Map,而不是 TreeMap。但是 Collectors 似乎没有 toTreeMap,我无法转换它 - 而且我不知道还能做什么。

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

【问题讨论】:

  • TLDR:技术上你不能。但是,还有另一种方法。我会在我的答案中发布它
  • 顺便说一句,你可以使用Entry.comparingByValue().reversed()
  • 使用接受供应商的Collectors.toMap的版本。为您的供应商提供一个方法,该方法返回一个新的TreeMap,并将适当的比较器传递给 ctor。

标签: java dictionary java-8 treemap


【解决方案1】:

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

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

这不会是TreeMap,但你的方法没有声明它返回一个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 或其他什么,但我现在将其保留为更简单的形式......)

【讨论】:

    猜你喜欢
    • 2022-12-09
    • 2023-03-10
    • 2021-10-04
    • 2019-01-15
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    相关资源
    最近更新 更多