按照值对 Map<Key, Value> 进行排序

1881
我需要根据值对一个Map进行排序。
由于值不是唯一的,我发现自己需要将keySet转换为数组,并通过使用自定义比较器对该数组进行排序,以便根据与键关联的值进行排序。
有没有更简单的方法?

32
地图的目的不是为了排序,而是为了快速访问。对象相等的值会违反地图的约束条件。使用entry set,例如 List<Map.Entry<...>> list =new LinkedList(map.entrySet())Collections.sort .... 进行排序。 - Hannes
2
一个可能出现这种情况的案例是当我们尝试在Java中使用计数器(Map<Object,Integer>)时。按出现次数排序将成为常见操作。像Python这样的语言具有内置的计数器数据结构。对于Java中的另一种实现方式,此处提供了一个示例。 - demongolem
14
有很多使用排序映射的情况,这就是为什么在jdk中有TreeMap和ConcurrentSkipListMap的原因。 - alobodzk
8
TreeMap和ConcurrentSkipListMap会根据键进行排序。问题是如何按值排序。 - Peter
3
根据您的使用情况,保留一个重复的TreeMap,将值映射到键可能是合理的。例如,您的常规map可能为"a"->5,"b"->7。而您的“排序”map可以有5->“a”,7->“b”。您只需在不同的地方使用适当的map,并努力始终同时修改这两个map。虽然存在许多警告和假设,但对于某些情况而言,与所有依赖于主动排序您的值的答案相比,这可能是一种简单而有效的答案。 - rococo
显示剩余2条评论
65个回答

-3
我们可以像这样简单地对一个映射进行排序。
            Map<String, String> unsortedMap = new HashMap<String, String>();

    unsortedMap.put("E", "E Val");
    unsortedMap.put("F", "F Val");
    unsortedMap.put("H", "H Val");
    unsortedMap.put("B", "B Val");
    unsortedMap.put("C", "C Val");
    unsortedMap.put("A", "A Val");
    unsortedMap.put("G", "G Val");
    unsortedMap.put("D", "D Val");

    Map<String, String> sortedMap = new TreeMap<String, String>(unsortedMap);

    System.out.println("\nAfter sorting..");
    for (Map.Entry <String, String> mapEntry : sortedMap.entrySet()) {
        System.out.println(mapEntry.getKey() + " \t" + mapEntry.getValue());

10
这只是创建一个树图,树图根据键排序。 - NimChimpsky

-5

最好的方法是将HashMap转换为TreeMap。 TreeMap可以自动对键进行排序。 如果你想按值排序,那么一个快速解决方法就是,如果你的值不重复,可以将值和键交换。


-8
如果您的Map值实现了Comparable接口(例如String),那么这应该可以工作。
Map<Object, String> map = new HashMap<Object, String>();
// Populate the Map
List<String> mapValues = new ArrayList<String>(map.values());
Collections.sort(mapValues);

如果地图值本身没有实现Comparable,但你有一个可以对它们进行排序的Comparable实例,请将最后一行替换为以下内容:
Collections.sort(mapValues, comparable);

1
同意。与其他提交的内容相比,这种方法简单且合理。我不确定为什么其他人建议使用更复杂的方法来解决这个问题,当集合已经为您完成了它。 - Aaron
20
原因是这种方法不能解决问题。虽然能成功排序值,但它会抛弃键(key)。问答要求的是一种可以排序map的方法,也就是说键和值应该仍然相连。 - gregory
3
无法正常工作,因为你只是排序了值的副本,因此未改变映射本身。 - whiskeysierra

-10

由于映射是无序的,我们可以按照以下方式进行排序

Map<String, String> map= new TreeMap<String, String>(unsortMap);

你应该注意,与哈希映射不同,树映射保证其元素按升序键排序。


9
该排序是基于键而不是值进行的。 - Duncan Jones

-11

使用java.util.TreeMap

“该映射根据其键的自然顺序进行排序,或者根据在创建映射时提供的比较器进行排序,具体取决于使用哪个构造函数。”


我会使用SortedMap接口和TreeMap一起使用。这样你就不会被TreeMap的实现所限制。 - ScArcher2
8
文档表明TreeMap根据其的自然顺序或您提供的比较器对键进行排序。但排序是基于键而不是值。比较值的比较器将给出与首先使用值作为键相同的树结构。 - benzado

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接