我正在阅读this article并尝试对文本文件中的某些单词进行计数,发现我无法对其在文章的列表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, Comparator.reverseOrder()))
可以写成:
.sorted(Comparator.comparing(Map.Entry::getValue).reversed())
为此,Java编译器抱怨:
错误:(46,49)java:无效方法引用非静态方法 无法从静态上下文引用getValue()
两个comparing
方法签名具有完全相同的第一个参数和静态范围,但前者有效,而后者则抱怨getValue
是非静态的。
我最初的想法是把它写成:
.sorted(Map.Entry.comparingByValue())
编译并运行但未反转。或者作为:
.sorted(Map.Entry.comparingByValue().reversed())
再次无法编译,给出错误消息:
错误:(48,62)java:不兼容的类型:java.util.Comparator&lt; java.util.Map.Entry&lt; java.lang.Object,V&gt;&gt;无法转换为java.util.Comparator&lt;? super java.util.Map.Entry&lt; java.lang.String,java.lang.Long&gt;&gt;
好的,那应该是:
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
哪个有效。
我似乎无法看到如何在我的“可写为”行中为Map.Entry::getValue
表单提供类似的泛型类型规范。
答案 0 :(得分:1)
至于为什么会发生这种情况:虽然类型推断在Java 8中已经突飞猛进,但如果将返回值分配给某些东西,它仍然只会使用返回目标类型。
在Java 7中,我们只能在赋值上下文中使用它(使用=
)并且它有点笨拙。在Java 8中,它不那么笨重,我们可以在调用上下文中使用它(作为方法参数传递,将其分配给形式参数)。
所以我理解它的方式,如果方法调用没有在赋值上下文或调用上下文中使用,目标类型推断就会关闭,因为它不再是一个叫做 poly的东西表达(15.12,18.5.2)。所以JLS说。
简而言之,目标类型推断仅在返回值为:
时才有效=
直接分配给变量,如v = foo();
。bar(foo())
。一旦您将方法调用链接起来,例如v = foo().zap()
,它就会停止工作。
取消我的评论:
我似乎无法看到如何为
Map.Entry::getValue
表单提供类似的泛型类型规范。
这将是Map.Entry<String, Long>::getValue
。