Java 使用 Collections.reverseOrder() 按值降序排列 TreeMap
Java order TreeMap by value descending using Collections.reverseOrder()
我想按降序对现有 TreeMap 进行排序(或将值从 Map 复制到 TreeMap,这无关紧要),按值(双精度)排序。
我知道这里有很多类似的问题,但是据我所知,在 Java8 中,您可以在不创建自己的比较器的情况下完成此操作,而是使用 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));
}
我知道这是行不通的,因为它 returns 是一个不声明任何顺序的地图,而不是 TreeMap。但是 Collectors 似乎没有 toTreeMap,我无法投射它 - 我不知道还能做什么。
或者也许它不能这样工作,我必须用另一种方式解决这个问题?
您可以利用 LinkedHashMap
将保留广告订单这一事实 - 因此在 toMap
调用中指定供应商,以便它会适当地创建 LinkedHashMap
:
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
LinkedHashMap::new));
那不会是 TreeMap
,但您的方法没有声明它 returns 是 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
或其他任何内容,但我现在将其保留为更简单的形式...)
我想按降序对现有 TreeMap 进行排序(或将值从 Map 复制到 TreeMap,这无关紧要),按值(双精度)排序。
我知道这里有很多类似的问题,但是据我所知,在 Java8 中,您可以在不创建自己的比较器的情况下完成此操作,而是使用 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));
}
我知道这是行不通的,因为它 returns 是一个不声明任何顺序的地图,而不是 TreeMap。但是 Collectors 似乎没有 toTreeMap,我无法投射它 - 我不知道还能做什么。
或者也许它不能这样工作,我必须用另一种方式解决这个问题?
您可以利用 LinkedHashMap
将保留广告订单这一事实 - 因此在 toMap
调用中指定供应商,以便它会适当地创建 LinkedHashMap
:
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
LinkedHashMap::new));
那不会是 TreeMap
,但您的方法没有声明它 returns 是 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
或其他任何内容,但我现在将其保留为更简单的形式...)