【问题标题】:Java 8 Map.Entry comparatorJava 8 Map.Entry 比较器
【发布时间】:2015-11-02 10:16:16
【问题描述】:

我一直在尝试使用 lambda 表达式在 Java8 中制作 Map.Entry Comparator,但发现了一个非常奇怪的行为。

Map<Integer, String> map = new TreeMap<>();

map.put(1, "Hello");
map.put(3, "zzzz");
map.put(2, "aaaa");
map.put(5, "AAAAA");
map.put(4, "aaaa");

Comparator<Map.Entry<Integer, String>> com = Comparator.comparing(Map.Entry::getValue);
com = com.reversed();

Comparator<Map.Entry<Integer, String>> com2 = Comparator.comparing(Map.Entry::getValue).reversed();

com 工作正常,但 com2 包含错误“无法解析方法 getValue”。我真的不知道为什么?有什么建议吗?

附:有什么方法可以避免用 Integer, String 输入 Map.Entry?有更短的方法吗?

【问题讨论】:

  • 这似乎是 Java 编译器如何推断泛型参数和 lambda 的返回类型的限制,因此您在这里可能无能为力。您可以等待编译器的下一个版本,它可能会更聪明。 :)

标签: java dictionary lambda java-8 comparator


【解决方案1】:

从 Java-8 开始,有一个独立的方法 Entry.comparingByValue 可以用来代替:

Comparator<Map.Entry<Integer, String>> com2 = 
        Map.Entry.<Integer, String>comparingByValue().reversed();

另一种方法是传递参数:

Comparator<Map.Entry<Integer, String>> com2 = 
        Map.Entry.comparingByValue(Comparator.reverseOrder());

这样就不需要类型参数了。

【讨论】:

    【解决方案2】:

    目前,您在指定方法引用时指定原始类型 - 在第一种情况下,赋值的泛型类型推断告诉编译器您的意思,但这不适用于方法调用的目标。不过,您可以为方法引用指定泛型类型:

    Comparator<Map.Entry<Integer, String>> com2 = 
        Comparator.comparing(Map.Entry<Integer,String>::getValue).reversed();
    

    (我意识到这增加了您在代码中需要Map.Entry&lt;Integer, String&gt; 的次数,但不幸的是,这在这里很难避免。)

    【讨论】:

    • 谢谢,比绝对有效!尽管 Intellij 显示了相同的警告。但是我可以避免输入这么多 Map.Entry 吗?
    • @ДмитрийКиселев:你也许可以通过编写你自己的调用reverse的实用方法来摆脱它,但它们在其他方面会很丑陋。 .
    猜你喜欢
    • 2016-12-30
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 2023-03-09
    • 2015-10-11
    • 2016-01-04
    • 2019-03-13
    相关资源
    最近更新 更多