【问题标题】:Sort HashMap descending by value and ascending by key at the same timeHashMap 按值降序同时按键升序排序
【发布时间】:2022-01-16 11:27:07
【问题描述】:

考虑以下哈希图:

HashMap<String, Double> cityScoreMap = new HashMap<>();

具有诸如

之类的值
CityB, 5.0
CityC, 10.0
CityA, 5.0

我需要按值对哈希图进行降序排序,但如果值相等,则按键升序排序:


CityC, 10.0 (highest value)
CityA, 5.0 (comes before CityB, because A < B)
CityB, 5.0 (comes after CityA)

到目前为止,我尝试按键分别排序,然后按值排序,但我不相信这种方法。 除了创建更多的哈希图之外,还有什么好的方法?

【问题讨论】:

  • Hashmap 未排序,无法排序。您可以使用带有适当比较器的 Treemap 来存储排序数据。但是,如果您只需要按排序顺序访问数据,则可以使用流,例如。
  • 我不熟悉Java,但是在c++中,如果你使用的是Hashmap,那么你不需要顺序,否则你会使用法线贴图。哈希图没有设计顺序
  • 最后你想要什么样的数据结构?如果您需要地图,那么您可能需要使用 TreeMap(查看官方文档了解更多信息)。
  • 如前所述,要么使用带有比较器的 TreeMap,要么使用按其键的插入顺序排序的 LinkedHashMap。
  • 您不能按值对任何类型的树进行排序,因为它是基于键的结构。

标签: java sorting hashmap


【解决方案1】:

实现这种 Map 的最简单方法是使用流。你必须实现一个比较器。

Map<String, Double> cityScoreMap = new HashMap<>();
cityScoreMap.put("CityB", 5.0);
cityScoreMap.put("CityC", 10.0);
cityScoreMap.put("CityA", 5.0);

Comparator<Map.Entry<String, Double>> descendingValueAscendingKeyComparator = (entry1, entry2) -> {
        //natural ordering of numbers is ascending, so comparing entry2 value to entry1 value makes for descending order
        int cmp = entry2.getValue().compareTo(entry1.getValue());
        if (cmp == 0) {
            //if comparison result is zero, that means values are equal, so we are comparing keys
            //we are comparing entry1 to entry2 keys for ascending order, which is natural for string
            return entry1.getKey().compareTo(entry2.getKey());
        }
        return cmp;
    };
cityScoreMap.entrySet()//get the set of entries in the map
            .stream()//stream the entries
            .sorted(descendingValueAscendingKeyComparator)//sort the entries with the supplied comparator
            .forEach(entry -> System.out.println(entry.getKey() + ", " + entry.getValue()));//print to verify ordering

比较器定义元素的顺序,这可能与它们的自然顺序不同。此比较器定义映射中条目(键值对)的顺序 - 首先按值降序,然后按键升序。这里的条目只是打印出来的,所以你可以看到顺序,但你也可以将它们存储在另一个结构中,这样可以保持它们的顺序 - 例如 LinkedHashMap,无论你的实际需要是什么。

您应该阅读以 javadoc 开头的 ComparatorComparable 接口。

【讨论】:

    猜你喜欢
    • 2011-11-05
    • 2021-09-29
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 2021-01-23
    • 2012-11-08
    相关资源
    最近更新 更多