SortedMap<Integer, Long> newMap = new TreeMap(new MyComparator(result));
newMap.putAll(result);
System.out.println("new map ---> " + newMap);
MyComparator.java
package com.example.admin.app;
import java.util.Comparator;
import java.util.Map;
class MyComparator implements Comparator {
Map map;
public MyComparator(Map map){
this.map = map;
}
public int compare (Object o1, Object o2) {
return ((Long) map.get(o2)).compareTo((Long) map.get(o1));
}
}
使用树形图比较器时,如果2个键的值相同,则比较器仅考虑第一个值,而忽略第二个值。
例如:未排序的地图-> {2 = 93085,1 = 93254,4 = 92928,9 = 93164,8 = 93085}
我写的代码的实际结果:{1 = 93254,9 = 93164,8 = 93085,4 = 92928}
我需要输出--{1 = 93254,9 = 93164,8 = 93085,2 = 93085,4 = 92928}
由于键2和8具有相同的值(93085),所以我只能得到一个。有人帮忙。
答案 0 :(得分:1)
当比较器报告键相等时,TreeMap
的一个属性就是将键视为相等(并且映射通常不支持多个相等键)。
…已排序的映射使用其
compareTo
(或compare
)方法执行所有键比较,因此,从已排序的映射的角度来看,此方法认为相等的两个键是相等的。
如果要防止键之间没有顺序时按键消失,则必须添加一个辅助顺序,以便在主顺序认为它们相等时使用。由于您的地图首先具有可比较的键,因此您可以利用其自然顺序来获得所需的结果:
class MyComparator implements Comparator<Integer> {
final Map<Integer, Long> map;
public MyComparator(Map<Integer, Long> map){
this.map = map;
}
public int compare(Integer o1, Integer o2) {
int c = Long.compare(map.get(o2), map.get(o1));
return c != 0? c: o2.compareTo(o1);
}
}
Map<Integer, Long> result = new HashMap<>();
result.put(2, 93085L);
result.put(1, 93254L);
result.put(4, 92928L);
result.put(9, 93164L);
result.put(8, 93085L);
SortedMap<Integer, Long> newMap = new TreeMap<>(new MyComparator(result));
newMap.putAll(result);
// new map ---> {1=93254, 9=93164, 8=93085, 2=93085, 4=92928}
System.out.println("new map ---> " + newMap);
或者,您可以使用LinkedHashMap
来维护插入顺序并使用已排序的列表来填充它:
List<Integer> list = new ArrayList<>(result.keySet());
Collections.sort(list, new MyComparator(result));
Map<Integer, Long> newMap = new LinkedHashMap<>();
for(Integer i: list) newMap.put(i, result.get(i));
System.out.println("new map ---> " + newMap);
这两种方法都会生成具有所需迭代顺序的映射。哪个更合适取决于以后的使用方式。
由于对列表进行排序不会消除重复项,因此它也可以与您的初始比较器一起使用,尽管我会使其类型安全:
class MyComparator implements Comparator<Integer> {
final Map<?, Long> map;
public MyComparator(Map<?, Long> map){
this.map = map;
}
public int compare(Integer o1, Integer o2) {
return Long.compare(map.get(o2), map.get(o1));
}
}
但是随后,没有指定具有相同值的条目的相对顺序。