Java使用Collections.reverseOrder()按值降序映射树图

Java使用Collections.reverseOrder()按值降序映射树图,java,dictionary,java-8,treemap,Java,Dictionary,Java 8,Treemap,我希望按降序对现有树映射进行排序(或者将值从映射复制到树映射,这无关紧要),并按值(双倍)排序 我知道这里有很多类似的问题,但是在Java8中,您可以不用创建自己的比较器,而是使用Collections.reverseOrder来完成这一任务 在某个地方,有一个答案正好描述了这一点。基于此,我尝试实现它: private Map<String, Double> orderByDescValue(Map<String, Double> unorderedMap) {

我希望按降序对现有树映射进行排序(或者将值从映射复制到树映射,这无关紧要),并按值(双倍)排序

我知道这里有很多类似的问题,但是在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));

}
私有映射orderByDescValue(映射无序映射){
Stream sorted=unorderedMap.entrySet().Stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue());
返回排序的.limit(配置.WORDCLOUD\u大小)
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
}
我知道这不起作用,因为它返回的是一个不断言任何顺序的映射,而不是一个树映射。但收藏家们似乎没有一个toTreeMap,我不能投它-我不知道还能做什么


或者它不能以这种方式工作,我必须以另一种方式解决这个问题?

您可以使用这样一个事实,即
LinkedHashMap
将保留插入顺序-因此在
toMap
调用中指定一个供应商,以便它可以适当地创建
LinkedHashMap

.collect(Collectors.toMap(
    Map.Entry::getKey,
    Map.Entry::getValue,
    (x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
    LinkedHashMap::new));
这不是一个
TreeMap
,但是您的方法没有声明它返回一个
TreeMap
,只是一个
映射。如果你真的,真的需要一个
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));
    }
}
此外,您不需要将方法限制为仅处理该类型的映射-您可以将其设置为泛型:

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));
}
私有静态映射orderByDescValue(映射无序映射){
返回unorderedMap.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(collector.toMap)(
Map.Entry::getKey,
Map.Entry::getValue,
(x,y)->{抛出新的非法状态异常(“意外合并请求”);},
LinkedHashMap::new));
}

(我确信我可以添加一堆
?扩展K
或任何东西,但我现在把它放在一个更简单的形式中…

您可以使用这样一个事实,即
LinkedHashMap
将保留插入顺序-因此在
toMap
调用中指定一个供应商,以便它将适当地创建
LinkedHashMap

.collect(Collectors.toMap(
    Map.Entry::getKey,
    Map.Entry::getValue,
    (x, y) -> { throw new IllegalStateException("Unexpected merge request"); },
    LinkedHashMap::new));
这不是一个
TreeMap
,但是您的方法没有声明它返回一个
TreeMap
,只是一个
映射。如果你真的,真的需要一个
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));
    }
}
此外,您不需要将方法限制为仅处理该类型的映射-您可以将其设置为泛型:

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));
}
私有静态映射orderByDescValue(映射无序映射){
返回unorderedMap.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(collector.toMap)(
Map.Entry::getKey,
Map.Entry::getValue,
(x,y)->{抛出新的非法状态异常(“意外合并请求”);},
LinkedHashMap::new));
}

(我肯定我可以添加一堆
?扩展K
或其他什么,但我现在把它放在一个更简单的形式中…

TLDR:从技术上讲,你不能。然而,还有另一种方法。我会在我的回答中发布。顺便说一句,你可以使用
Entry.comparingByValue().reversed()
使用带有供应商的
Collectors.toMap版本。作为您的供应商,提供一种方法,返回一个新的
TreeMap
,并将适当的比较器传递给ctor。TLDR:从技术上讲,您不能。然而,还有另一种方法。我会在我的回答中发布。顺便说一句,你可以使用
Entry.comparingByValue().reversed()
使用带有供应商的
Collectors.toMap版本。作为供应商提供一种方法,该方法返回一个新的
TreeMap
,并将适当的比较器传递给ctor。