Java 为什么stream sorted()无法推断我的类型?

Java 为什么stream sorted()无法推断我的类型?,java,java-stream,Java,Java Stream,我正在阅读并尝试计算文本文件中的一些单词,发现我无法像文章的清单1所示那样反向排序 我有一些代码可以工作: public class WordCounter { public static final PrintWriter out = new PrintWriter(System.out, true); public static void main(String... args) throws IOException { //The need to put

我正在阅读并尝试计算文本文件中的一些单词,发现我无法像文章的清单1所示那样反向排序

我有一些代码可以工作:

public class WordCounter {
    public static final PrintWriter out = new PrintWriter(System.out, true);

    public static void main(String... args) throws IOException {
        //The need to put "", in front of args in the next line is frustrating.
        try (Stream<String> lines = Files.lines(Paths.get("", args))) {
            lines.parallel()
              .map(l -> l.toLowerCase().replaceAll("[^a-z\\s]", "").split("\\s"))
              .flatMap(Arrays::stream)
              .filter(s -> !s.isEmpty())
              .collect(Collectors.groupingBy(
                      Function.identity(), Collectors.counting()))
                // Sort Map<K,V> Entries by their Integer value descending
                .entrySet().parallelStream()
// MY QUESTION IS ABOUT THIS METHOD:
                  .sorted(
                    Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()))
// --------------------------------- //
                  .forEachOrdered(e -> out.printf("%5d\t%s\n", e.getValue(), e.getKey()));
        }
        out.close();
    }
}
可以写成:

.sorted(Comparator.comparing(Map.Entry::getValue).reversed())
但是,Java编译器对此抱怨:

错误:(46,49)java:无效的方法引用非静态方法 无法从静态上下文引用getValue()

两个
比较
方法签名具有完全相同的第一个参数和静态范围,但前者有效,而后者抱怨
getValue
是非静态的

我最初的想法是将其写成:

.sorted(Map.Entry.comparingByValue())
可编译并运行,但不会反转。或作为:

.sorted(Map.Entry.comparingByValue().reversed())
它再次无法编译,并给出以下错误消息:


错误:(48,62)java:不兼容的类型:java.util.Comparator无法转换为java.util.Comparator至于为什么会发生这种情况:虽然java 8中的类型推断已经实现了飞跃,但如果返回值被分配给某个对象,它仍然只会使用返回目标类型

在Java7中,我们只能在赋值上下文中使用它(使用
=
),它有点笨重。在Java8中,它不那么笨重,我们可以在调用上下文中使用它(作为方法参数传递,将其分配给形式参数)

按照我的理解,如果方法调用没有在赋值上下文或调用上下文中使用,那么目标类型推断就会关闭,因为它不再是所谓的多边形表达式(,)。JLS如是说

简言之,目标类型推断仅在返回值为:

  • 使用
    =
    直接分配给变量,如
    v=foo()
  • 直接传递给方法,如在
    bar(foo())
一旦你将一个方法调用链接进来,比如
v=foo().zap()
,它就会停止工作


摘自我的评论:

但是,我似乎看不到如何为
Map.Entry::getValue
表单提供类似的通用类型规范


这将是
Map.Entry::getValue

“我似乎看不出如何为Map.Entry::getValue表单提供类似的通用类型规范。”
Map.Entry::getValue
不幸的是,类型推断仍然有局限性。@Radiodef谢谢;所以我的IDE(IDEA CE 15)会在这里突出显示
getValue
,并抱怨找不到对方法的引用。但是,它编译和运行正确,这意味着IDEA使用的内部Java编译或语法检查器与实际的Java不一致。这可能是IntelliJ错误。我也不知道为什么在一个案例中它会给你一个“静态上下文”错误消息。@Radiodef如果你这样填写,我很乐意接受你的答案。它确实回答了我的问题。
.sorted(Map.Entry.comparingByValue().reversed())
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())