这是通用的版本:
public class MapUtil {
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Entry<K, V>> list = new ArrayList<>(map.entrySet());
list.sort(Entry.comparingByValue());
Map<K, V> result = new LinkedHashMap<>();
for (Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
}
Java 8提供了一个新的答案:将条目转换为流,并使用Map.Entry中的比较器组合器:
Stream<Map.Entry<K,V>> sorted =
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue());
这将使您可以使用按值升序排序的条目。如果要递减值,只需反转比较器:
Stream<Map.Entry<K,V>> sorted =
map.entrySet().stream()
.sorted(Collections.reverSEOrder(Map.Entry.comparingByValue()));
如果这些值不具有可比性,则可以传递一个显式比较器:
Stream<Map.Entry<K,V>> sorted =
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(comparator));
然后,您可以继续使用其他流操作来消耗数据。例如,如果要在新地图中排名前10位:
Map<K,V> topTen =
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverSEOrder()))
.limit(10)
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
或打印到System.out:
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.forEach(System.out::println);
private static <K, V> Map<K, V> sortByValue(Map<K, V> map) {
List<Entry<K, V>> list = new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Object>() {
@SuppressWarnings("unchecked")
public int compare(Object o1, Object o2) {
return ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue());
}
});
Map<K, V> result = new LinkedHashMap<>();
for (Iterator<Entry<K, V>> it = list.iterator(); it.hasNext();) {
Map.Entry<K, V> entry = (Map.Entry<K, V>) it.next();
result.put(entry.getKey(), entry.getValue());
}
return result;
}