繁体   English   中英

按值排序HashMaps

[英]Sorting HashMaps by value

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

例如: 按值(Java)对Map <Key,Value>进行排序

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

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

我将丢弃可以按值的顺序迭代的Map作为“如何做到”的另一个答案,但是......具体来说,这个解决方案不会返回阻塞的地图(通过抛出异常)查询不在原始地图中的键。

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

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

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

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

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

提供了Multimap文档。

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

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 

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM