当我需要按值对HashMap进行排序时,建议似乎是创建HashMap,然后将数据放入按值排序的TreeMap中。
例如:Sort a Map<Key, Value> by values (Java)
我的问题:为什么有必要这样做?为什么不创建一个TreeMap(按键排序),然后按值对其进行排序?
答案 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>());
答案 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());