我对Java比较陌生,经常发现需要对值进行Map<Key,Value>排序。
由于这些值不是唯一的,我发现自己将keySet转换为一个数组,并使用自定义比较器通过数组排序对该数组进行排序,该比较器根据与该键关联的值进行排序。
有没有更简单的方法?
我对Java比较陌生,经常发现需要对值进行Map<Key,Value>排序。
由于这些值不是唯一的,我发现自己将keySet转换为一个数组,并使用自定义比较器通过数组排序对该数组进行排序,该比较器根据与该键关联的值进行排序。
有没有更简单的方法?
当前回答
我们只需像这样对地图进行排序
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());
其他回答
Java 8提供了一个新的答案:将条目转换为流,并使用Map中的比较器组合符。条目:
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));
上面看到的LinkedHashMap按插入顺序迭代条目。
或打印到System.out:
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.forEach(System.out::println);
您可以尝试Guava的多功能地图:
TreeMap<Integer, Collection<String>> sortedMap = new TreeMap<>(
Multimaps.invertFrom(Multimaps.forMap(originalMap),
ArrayListMultimap.<Integer, String>create()).asMap());
因此,您将获得从原始值到对应于它们的键集合的映射。即使同一值有多个键,也可以使用此方法。
根据上下文,使用java.util.LinkedHashMap<T>来记住项目在映射中的放置顺序。否则,如果您需要根据值的自然排序对值进行排序,我建议您维护一个单独的List,该List可以通过Collections.sort()进行排序。
从…起http://www.programmersheaven.com/download/49349/download.aspx
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;
}
使用通用比较器,例如:
final class MapValueComparator<K,V extends Comparable<V>> implements Comparator<K> {
private final Map<K,V> map;
private MapValueComparator() {
super();
}
public MapValueComparator(Map<K,V> map) {
this();
this.map = map;
}
public int compare(K o1, K o2) {
return map.get(o1).compareTo(map.get(o2));
}
}