我有一张地图,我想按两个因素排序:
1) the int value of each element; and then
2) the length of key of each element.
这个泛型函数可以按值排序,以及如何使它适用于1)和2)的排序?
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> unsortMap) {
List<Map.Entry<K, V>> list = new LinkedList<>(unsortMap.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
return (o2.getValue()).compareTo(o1.getValue());
}
});
Map<K, V> result = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
编辑:这个版本不能正常工作。怎么了?
public static Map<String, Integer> sortByValueWithGenerics(Map<String, Integer> unsortMap) {
List<Map.Entry<String, Integer>> list =
new LinkedList<Map.Entry<String, Integer>>(unsortMap.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> o1,
Map.Entry<String, Integer> o2) {
int c = (o1.getValue()).compareTo(o2.getValue());
if (c < 0) {
if(o2.getKey().length() >o1.getKey().length()){
c=-1;
}
}
return c;
}
});
Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
for (Map.Entry<String, Integer> entry : list) {
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
答案 0 :(得分:1)
您的if
条件应检查先前的比较是否返回0
然后执行以下比较:
if (c == 0)
return Integer.compare(o1.getKey().length(), o2.getKey().length());
另外,请注意我已经将o1.getKey().length()
作为Integer.compare
方法的第一个参数传递,而不是将其作为第二个参数传递给您。
现在,您的比较器读作“按值排序,如果两个给定值相等,则按键升序的长度排序”。
从java-8开始,您可以进一步简化排序逻辑:
list.sort(Map.Entry.<String, Integer>comparingByValue()
.thenComparingInt(e -> e.getKey().length());
或者如果你想变得更加漂亮,那么整个方法可以变成:
public static Map<String, Integer> sortByValueThenByKey(Map<String, Integer> unsortMap) {
return unsortMap.entrySet()
.stream()
.sorted(Map.Entry.<String, Integer>comparingByValue()
.thenComparingInt(e -> e.getKey().length()))
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue,(oldValue, newValue) -> newValue,
LinkedHashMap::new));
}