我想按降序排序现有的TreeMap(或将Map中的值复制到TreeMap中,无关紧要),按值排序(双打)。
我知道这里发布了很多类似的问题,但是在Java8中,你可以在不创建自己的Comparator但是使用Collections.reverseOrder的情况下完成此任务。
某处有一个答案正是如此描述的。基于此,我试图实现它:
private Map<String, Double> orderByDescValue(Map<String, Double> unorderedMap) {
Stream<Map.Entry<String,Double>> sorted = unorderedMap.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
return sorted.limit(Configuration.WORDCLOUD_SIZE)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
我理解这不起作用,因为它返回一个Map,它不会断言任何顺序,而不是TreeMap。但收藏家似乎没有toTreeMap,我无法施展它 - 我不知道还能做什么。
或许它不能以这种方式工作,我必须以另一种方式解决这个问题?
答案 0 :(得分:4)
您可以使用LinkedHashMap
将保留广告订单的事实 - 因此请在toMap
来电中指定供应商,以便适当地创建LinkedHashMap
:
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
LinkedHashMap::new));
这不是TreeMap
,但您的方法并未声明它返回TreeMap
,只返回Map
。如果你确实需要一个TreeMap
,我建议你更改签名 - 但这很奇怪,因为TreeMap
按键而不是值排序。
完整示例:
import java.util.*;
import java.util.stream.*;
public class Test {
public static void main(String[] args) throws Exception {
Map<String, Double> unordered = new HashMap<>();
unordered.put("a", 10.5);
unordered.put("b", 5.3);
unordered.put("c", 12.7);
unordered.put("d", 6.0);
Map<String, Double> ordered = orderByDescValue(unordered);
for (Map.Entry<String, Double> entry : ordered.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
private static Map<String, Double> orderByDescValue(Map<String, Double> unorderedMap) {
return unorderedMap.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
LinkedHashMap::new));
}
}
输出:
c: 12.7
a: 10.5
d: 6.0
b: 5.3
此外,您不需要将方法限制为仅处理该类型的地图 - 您可以将其设为通用:
private static <K, V extends Comparable<V>> Map<K, V> orderByDescValue(Map<K, V> unorderedMap) {
return unorderedMap.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
LinkedHashMap::new));
}
(我确信我可以添加一堆? extends K
或其他什么,但我现在已经把它留在一个更简单的形式......)