【问题标题】:How can I sort the keys of a Map in Java?如何在 Java 中对 Map 的键进行排序?
【发布时间】:2018-11-16 18:17:08
【问题描述】:

这是一个非常基本的问题,我只是不太擅长 Java。我有一个 Map,我想按排序顺序获取一个列表或一些键,以便我可以遍历它们。

【问题讨论】:

    标签: java


    【解决方案1】:

    使用TreeMap,它是SortedMap 接口的实现。它按排序顺序显示其键。

    Map<String, Object> map = new TreeMap<String, Object>();
    /* Add entries to the map in any order. */
    ...
    /* Now, iterate over the map's contents, sorted by key. */
    for (Map.Entry<String, ?> entry : map.entrySet()) {
      System.out.println(entry.getKey() + ": " + entry.getValue());
    }
    

    如果您正在使用未按您喜欢的方式排序的另一个 Map 实现,您可以将它传递给 TreeMapconstructor 以创建具有排序键的新映射。

    void process(Map<String, Object> original) {
      Map<String, Object> copy = new TreeMap<String, Object>(original);
      /* Now use "copy", which will have keys in sorted order. */
      ... 
    }
    

    TreeMap 可与任何类型的实现 Comparable 接口的键配合使用,将它们置于“自然”顺序。对于不是Comparable 的键,或者其自然顺序不是您所需要的,您可以实现自己的Comparator 并在constructor 中指定。

    【讨论】:

    • 我正在使用的代码给了我一个 Map 对象,那么我该如何将其转换为 TreeMap 或使用 TreeMap 进行排序?
    • 您可以使用参数为任意 Map 的构造函数来创建 TreeMap。另外,恭喜埃里克森(我假设,因为你距离 10k 只有 5 个代表)。
    • 您最好对键进行排序(放置在 TreeSet 中),然后在原始地图上调用 get。创建一个新的 TreeMap 会导致所有内容都被重新散列。
    • 史蒂夫,这是不正确的。 TreeMap 不会发生散列;这是一棵红黑树。无论如何,TreeSet 委托给内部 TreeMap,因此创建 TreeSet、迭代其键并使用它们在另一棵树中执行 O(log(n)) 查找会令人困惑且效率低下。
    【解决方案2】:

    您有多种选择。按优先顺序列出:

    1. 使用SortedMap:
      SortedMap&lt;whatever&gt; myNewMap = new TreeMap&lt;whatever&gt;(myOldMap);
      如果您想多次迭代,这是非常可取的。它使键保持排序,因此您不必在迭代之前对其进行排序。
    2. 没有#2。
    3. 也没有#3。
    4. SortedSet&lt;whatever&gt; keys = new TreeSet&lt;whatever&gt;(myMap.keySet());
    5. List<whatever> keys = new ArrayList<whatever>(myMap.keySet()); Collections.sort(keys);

    最后两个会得到你想要的,但只有当你只想迭代一次然后忘记整个事情时才应该使用。

    【讨论】:

    • 在第 4 步中,您还可以创建一个 TreeSet(一个排序集)而不是一个列表,这样您就不必显式调用 sort()。
    • @David:我确实想到了这一点,但由于某种原因,我忘记了可以迭代 Set。不过,它确实需要每次都进行排序。
    • 嗯我喜欢#4。为什么它需要比 #1 更多的排序?我会认为它同样好
    • @litb:如果您每次想要迭代地图时都将地图转储到 TreeMap 中,那么您是对的,它们是相同的。
    • 如果您也需要地图中的值,#4 不如 #1 好。遍历条目可以节省对值的额外查找。
    【解决方案3】:

    您可以在迭代时创建一个排序集合,但首先拥有一个排序映射更有意义。 (正如已经建议的那样)

    都一样,这就是你的做法。

    Map<String, Object> map;
    for(String key: new TreeSet<String>(map.keySet()) {
      // accessed in sorted order.
    }
    

    【讨论】:

      【解决方案4】:

      除了其他答案中提到的方法之外,对于 Java 8 流,从映射中获取排序键列表的另一种简写方式是 -

      List<T> sortedKeys = myMap.keySet().stream().sorted().collect(Collectors.toList());
      

      实际上也可以在.sorted() 之后完成工作(例如使用.map(...).forEach(...)),而不是将其收集到列表中然后遍历列表。

      【讨论】:

        猜你喜欢
        • 2010-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-03
        • 2016-09-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多