按值排序HashMap

时间:2012-02-06 22:26:30

标签: java hashmap

当我需要按值对HashMap进行排序时,建议似乎是创建HashMap,然后将数据放入按值排序的TreeMap中。

例如:Sort a Map<Key, Value> by values (Java)

我的问题:为什么有必要这样做?为什么不创建一个TreeMap(按键排序),然后按值对其进行排序?

4 个答案:

答案 0 :(得分:2)

因为您无法手动重新排序TreeMap的条目。 TreeMap条目总是按键排序。

我将抛​​弃Map that could be iterated in the order of values作为“如何做到”的另一个答案,但是......具体来说,这个解决方案不会返回一个地图,该地图会对查询进行扼流(通过抛出异常)键不在原始地图中。

答案 1 :(得分:2)

如果您知道您的值是唯一的,则可以使用Guava的BiMap(双向映射)来存储数据。像HashBiMap一样创建HashMap,然后从其反向创建新的TreeMap

new TreeMap<>(biMap.inverse());

然后将按值对该地图进行排序。请记住,您所想的“键”和“值”将被交换。

如果您的值不是唯一的,则可以创建反向的多图。 multimap实质上是从每个键到一个或多个值的映射。它通常通过制作从键到列表的映射来实现。你不必这样做,因为谷歌为你做了。只需从现有地图创建一个多图,然后让Guava将它反转为TreeMultimap,正如您所猜测的那样,TreeMap可以为每个键保存多个值。

Multimaps.invertFrom(Multimaps.forMap(myMap), new TreeMultimap<V, K>());

Multimap documentation is provided.

答案 2 :(得分:1)

我有这个非常小的代码,工作正常:

public class SortMapByValues {
    public static void main(String[] args) {

        Map<Integer, String> myMap = new LinkedHashMap<Integer, String>();

        myMap.put(100, "hundread");
        myMap.put(500, "fivehundread");
        myMap.put(250, "twofifty");
        myMap.put(300, "threehundread");
        myMap.put(350, "threefifty");
        myMap.put(400, "fourhundread");

        myMap = sortMapByValues(myMap);

        for (Map.Entry<Integer, String> entry : myMap.entrySet()) {
            System.out.println(entry.getKey() + " " + entry.getValue());
        }

    }

    public static Map<Integer, String> sortMapByValues(
            Map<Integer, String> firstMap) {
        Map<String, Integer> SecondyMap = new TreeMap<String, Integer>();

        for (Map.Entry<Integer, String> entry : firstMap.entrySet()) {
            SecondyMap.put(entry.getValue(), entry.getKey());
        }
        firstMap.clear();
        for (Map.Entry<String, Integer> entry : SecondyMap.entrySet()) {
            firstMap.put(entry.getValue(), entry.getKey());
        }
        return firstMap;
    }

}

<强>输出:

500 fivehundread  
400 fourhundread  
100 hundread  
350 threefifty  
300 threehundread  
250 twofifty 

答案 3 :(得分:1)

我使用Java 8 Stream API编写了以下单行代码,按值对任何给定的地图进行排序:

List<Map.Entry<String, String>> sortedEntries = map.entrySet().stream()
  .sorted((o1, o2) -> o1.getValue().compareTo(o2.getValue())).collect(Collectors.toList());