逆序排序中的方法引用
问题
在Stream API中或其他排序方法中
LinkedHashMap<String, Long> sortedKeywords = keywordCount.entrySet().stream()
.sorted(Comparator.comparingLong(Map.Entry::getValue).reversed())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, LinkedHashMap::new));
IDEA会提示错误:Not-static method cannot be referenced from a static context
问题说明
- stream中的顺序排列
使用Comparator.comparingLong(Map.Entry::getValue)
完成顺序排列
// 正序排序没有任何问题
LinkedHashMap<String, Long> sortedKeywords = keywordCount.entrySet().stream()
.sorted(Comparator.comparingLong(Map.Entry::getValue))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, LinkedHashMap::new));
- 逆序排列
Comparator.comparingLong(Map.Entry::getValue).reversed()
则会出现错误提示Not-static method cannot be referenced from a static context
// 逆序排序就会IDEA就会提示编译错误:`Not-static method cannot be referenced from a static context`
LinkedHashMap<String, Long> sortedKeywords = keywordCount.entrySet().stream()
.sorted(Comparator.comparingLong(Map.Entry::getValue).reversed())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, LinkedHashMap::new));
上面这个提示是有误导性质的,实际上是因为Java无法推断类型,所以只要明确类型信息就可以(这一点确实很奇怪,因为在我们看来,类型信息明明是已经存在的。而且使用别的类型,IDEA也会报错,也侧面证明,类型信息确实可以推断出来。进一步的问题排查还需要了解更多Java的类型推断
- 编译还会生成如下错误信息
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project tenbot: Compilation failure: Compilation failure:
[ERROR] /E:/Workspace/tenbot/src/main/java/com/tencent/iask/tenbot/util/HanLpUtil.java:[38,49] 不兼容的类型: 无法推断类型变量 T
[ERROR] (参数不匹配; 方法引用无效
[ERROR] 无法将 接口 java.util.Map.Entry<K,V>中的 方法 getValue应用到给定类型
[ERROR] 需要: 没有参数
[ERROR] 找到: java.lang.Object
[ERROR] 原因: 实际参数列表和形式参数列表长度不同)
[ERROR] /E:/Workspace/tenbot/src/main/java/com/tencent/iask/tenbot/util/HanLpUtil.java:[38,53] 方法引用无效
[ERROR] 无法从静态上下文中引用非静态 方法 getValue()
- 修复错误:增加类型信息
Comparator.comparingLong(Map.Entry<String, Long>::getValue).reversed()
LinkedHashMap<String, Long> sortedKeywords = keywordCount.entrySet().stream()
.sorted(Comparator.comparingLong(Map.Entry<String, Long>::getValue).reversed())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, LinkedHashMap::new));
问题解释
这里实际上是Java的类型推断的问题,不过跟javac的一个bug混淆了,就生成这么一个有误导性质的错误提示。如果是在Java 9中则会提示参数不匹配; 方法引用无效
ps: 为什么会存在类型推断错误?思考了半天也没弄明白,希望高人解答
网友评论