[英]Comparator for MultiSet.Entry and Generics
我需要一个用于番石榴MultiSet.Entry的比较器,以便首先按计数排序,然后按字符串排序。 但是,我遇到了编译器问题,并且我认为泛型错误了。
这样编译:
Comparator<Multiset.Entry<String>> comparator() {
return Comparator.comparing(Multiset.Entry::getCount);
}
但是,这不是:
Comparator<Multiset.Entry<String>> comparator() {
return Comparator.comparing(Multiset.Entry::getCount).thenComparing(Multiset.Entry::getElement);
}
Error: java: incompatible types: cannot infer type-variable(s) T,U (argument mismatch; invalid method reference method getCount in interface com.google.common.collect.Multiset.Entry cannot be applied to given types required: no arguments found: java.lang.Object reason: actual and formal argument lists differ in length)
如果我将比较器(例如一个字符串)组合在一起,那么我显然不会遇到类似的问题。
Comparator<String> comparator2() {
return Comparator.comparing(String::length).thenComparing(String::toString);
}
我在这里想念的是什么,如何使它工作?
(注意:我知道番石榴可能有不同的方法,但是我想了解我遇到的问题。)
我认为这是因为类型定位(Java推理的一种形式)与代码中使用的点功能编程一起工作的原因(您可以在Java文档中阅读有关目标类型的信息 ,特别是称为“ Target Types and Method Arguments
)。
简而言之,如果我有这样的事情:
List<String> list = new List<>();
这里的目标类型是List<String>
因此Java(8)认识到您要创建的新列表已分配给它,并且应该是List<String>
类型,因此可以推断该类型,而不必指定类型参数。
最初编译的最简短的内容是:代码部分Comparator.comparing(Multiset.Entry::getCount);
返回Comparator<T>
的类型,此结果立即分配给方法的返回类型(即方法的返回类型是目标类型)。 编译器可以推断类型,因为目标类型是方法comparator
的返回类型,您已在方法签名中将其明确定义/捕获为Comparator<Multiset.Entry<String>>
。 该T
在Comparator<T>
因此,可以推断。
在第二段代码中(您不会编译并需要显式类型见证参数-方法调用中<>中的显式位),您正在使用链接方法的点运算符。 这意味着将第二部分thenComparing(Multiset.Entry::getElement)
应用于第一部分Comparator.comparing(Multiset.Entry::getCount)
。
第二部分可以从目标类型推断类型,因为第二部分的结果是方法返回的结果,所以第二部分的目标类型类似于上面进行编译的情况-方法返回类型为捕获并定义,因此可以推断出这一点。
但是对于第一部分,目标类型是不确定的,因为没有将其分配给具有实际类型的某种类型。 根据Comparator API, Comparator<T>
是该函数返回的内容,但是由于它不知道具体要分配给哪种类型,因此您需要提供类型见证并在返回时明确指定Comparator<T>
T
(在您的情况下)应为Multiset.Entry<String>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.