我对Java比较陌生,经常发现需要对值进行Map<Key,Value>排序。
由于这些值不是唯一的,我发现自己将keySet转换为一个数组,并使用自定义比较器通过数组排序对该数组进行排序,该比较器根据与该键关联的值进行排序。
有没有更简单的方法?
我对Java比较陌生,经常发现需要对值进行Map<Key,Value>排序。
由于这些值不是唯一的,我发现自己将keySet转换为一个数组,并使用自定义比较器通过数组排序对该数组进行排序,该比较器根据与该键关联的值进行排序。
有没有更简单的方法?
当前回答
我的解决方案是一种非常简单的方法,使用大多数给定的API。我们使用Map的特性通过entrySet()方法将其内容导出为Set。我们现在有一个包含Map.Entry对象的集合。
好的,集合不携带订单,但我们可以将内容放入ArrayList。它现在有一个随机顺序,但无论如何我们都会对它进行排序。
由于ArrayList是一个集合,所以我们现在使用Collections.sort()方法来将秩序带入混乱。因为我们的Map.Entry对象没有实现我们需要的那种比较,所以我们提供了一个自定义比较器。
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("Z", "E");
map.put("G", "A");
map.put("D", "C");
map.put("E", null);
map.put("O", "C");
map.put("L", "D");
map.put("Q", "B");
map.put("A", "F");
map.put(null, "X");
MapEntryComparator mapEntryComparator = new MapEntryComparator();
List<Entry<String,String>> entryList = new ArrayList<>(map.entrySet());
Collections.sort(entryList, mapEntryComparator);
for (Entry<String, String> entry : entryList) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
}
其他回答
我们只需像这样对地图进行排序
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());
这太复杂了。地图不应该按价值排序。最简单的方法是创建自己的类,以满足您的需求。
在下面的示例中,您应该在*所在的位置添加TreeMap比较器。但通过javaAPI,它只提供比较器键,而不提供值。此处所述的所有示例均基于2个地图。一个哈希和一个新树。这很奇怪。
示例:
Map<Driver driver, Float time> map = new TreeMap<Driver driver, Float time>(*);
因此,通过以下方式将地图更改为集合:
ResultComparator rc = new ResultComparator();
Set<Results> set = new TreeSet<Results>(rc);
您将创建类Results,
public class Results {
private Driver driver;
private Float time;
public Results(Driver driver, Float time) {
this.driver = driver;
this.time = time;
}
public Float getTime() {
return time;
}
public void setTime(Float time) {
this.time = time;
}
public Driver getDriver() {
return driver;
}
public void setDriver (Driver driver) {
this.driver = driver;
}
}
以及Comparator类:
public class ResultsComparator implements Comparator<Results> {
public int compare(Results t, Results t1) {
if (t.getTime() < t1.getTime()) {
return 1;
} else if (t.getTime() == t1.getTime()) {
return 0;
} else {
return -1;
}
}
}
这样,您可以轻松添加更多依赖项。
最后一点,我将添加简单迭代器:
Iterator it = set.iterator();
while (it.hasNext()) {
Results r = (Results)it.next();
System.out.println( r.getDriver().toString
//or whatever that is related to Driver class -getName() getSurname()
+ " "
+ r.getTime()
);
}
给定的地图
Map<String, Integer> wordCounts = new HashMap<>();
wordCounts.put("USA", 100);
wordCounts.put("jobs", 200);
wordCounts.put("software", 50);
wordCounts.put("technology", 70);
wordCounts.put("opportunity", 200);
根据值按升序对地图进行排序
Map<String,Integer> sortedMap = wordCounts.entrySet().
stream().
sorted(Map.Entry.comparingByValue()).
collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
System.out.println(sortedMap);
根据值按降序排序地图
Map<String,Integer> sortedMapReverseOrder = wordCounts.entrySet().
stream().
sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).
collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
System.out.println(sortedMapReverseOrder);
输出:
{软件=50,技术=70,美国=100,工作=200,机会=200}
{工作岗位=200,机会=200,美国=100,技术=70,软件=50}
使用java.util.TreeMap。
映射根据其键的自然顺序进行排序,或由创建映射时提供的Comparator进行排序,具体取决于使用的构造函数
使用通用比较器,例如:
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));
}
}