Java 使用双功能代替比较器不起作用
在初始化诸如Java 使用双功能代替比较器不起作用,java,generics,lambda,java-8,functional-interface,Java,Generics,Lambda,Java 8,Functional Interface,在初始化诸如TreeMap、TreeSet等集合时,我们可以添加自定义比较器。 代码如下所示: Map<Integer, String> map1 = new TreeMap<>(new Comparator<Integer>() { public int compare(Integer x, Integer y) { return x-y; } }); map1=newtreemap(newcomparator(){ 公共整
TreeMap
、TreeSet
等集合时,我们可以添加自定义比较器。
代码如下所示:
Map<Integer, String> map1 = new TreeMap<>(new Comparator<Integer>() {
public int compare(Integer x, Integer y) {
return x-y;
}
});
map1=newtreemap(newcomparator(){
公共整数比较(整数x,整数y){
返回x-y;
}
});
现在,我们可以使用lambda表达式替换这个匿名实现。代码如下所示:
Map<Integer, String> map2 = new TreeMap<>((x,y) -> x-y);
map2=newtreemap((x,y)->x-y);
Java-8允许通过将lambda表达式存储在变量中。因此,我将上述代码修改为:
BiFunction<Integer, Integer, Integer> myComparator = (x,y) -> x-y;
Map<Integer, String> map3 = new TreeMap<>(myComparator);
双功能myComparator=(x,y)->x-y;
Map map3=新树形图(myComparator);
但最后一次尝试没有成功!它给出了以下错误:
无法推断树映射的类型参数
为什么在上一个示例中它无法解析类型
注意:为了确认这不是一个IDE错误,我使用
javac
执行了一次原始编译,它仍然给出了相同的错误。尽管lambda表达式看起来是相同的,但不是相同的,因此您无法交换它们
Comparator<Integer> comparator = (x,y) -> x - y;
Map<Integer, String> map3 = new TreeMap<>(comparator);
比较器比较器=(x,y)->x-y;
Map map3=新树形图(比较器);
让我们更深入地了解这些接口,并使用匿名类实现它们:
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer x, Integer y) {
return x - y;
}
};
BiFunction<Integer, Integer, Integer> biFun = new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(final Integer x, final Integer y) {
return x - y;
}
};
比较器比较器=新比较器(){
@凌驾
公共整数比较(整数x,整数y){
返回x-y;
}
};
双功能biFun=新的双功能(){
@凌驾
公共整数应用(最终整数x,最终整数y){
返回x-y;
}
};
不同之处还在于方法的名称。由于其内部实现将根据与的合同调用compare
,因此在其构造函数中预期
顺便说一句,结果也是相同的lambda表达式。这仅仅是因为
TreeMap
构造函数需要比较器,而不是双函数
通过编写BiFunction myComparator=…
可以明确地告诉编译器变量属于该类型。这可以防止编译器推断TreeMap
构造函数所需的类型。由于BiFunction
不是一个比较器,也不是它的子类,编译器不允许这样做。因为它需要比较器,而您提供了BiFunction。
从Oracle文档:
@FunctionalInterface
public interface Comparator<T>
@functioninterface
公共接口比较器
一种比较函数,它对某些对象集合施加总排序。可以将比较器传递给排序方法(如Collections.sort或Arrays.sort),以允许对排序顺序进行精确控制。比较器还可用于控制某些数据结构(如排序集或排序映射)的顺序,或为没有自然顺序的对象集合提供顺序
您不能将lambda函数声明为Comparator myComparator=(x,y)->x-y代码>而不是双功能
?因为Comparator
是TreeMap
构造函数需要的类型。我得到了一个“无法解析构造函数…”@luk2302,您使用的是哪个版本的java?@khelwood有效!!。但不幸的是,这并不能解决问题。不管你实现了哪种逻辑,都不要使用负号。有Integer.compare(int,int)
做正确的事情,但是通常,当您最后比较两个int
值时,您可以使用Comparator.naturalOrder()
,Comparator.reverseOrder()
,Comparator.comparingit(…)
,或它们的组合。