使用BiFunction代替比较器不起作用

Adi*_*pta 3 java lambda comparator java-8 functional-interface

在初始化集合(如TreeMapTreeSet等)时,我们可以添加自定义比较器。该代码如下所示:

Map<Integer, String> map1 = new TreeMap<>(new Comparator<Integer>() {
    public int compare(Integer x, Integer y) {
        return x-y;
    }
});
Run Code Online (Sandbox Code Playgroud)

现在,我们可以用lambda表达式替换此匿名实现。代码如下所示:

Map<Integer, String> map2 = new TreeMap<>((x,y) -> x-y);
Run Code Online (Sandbox Code Playgroud)

Java-8允许您通过功能接口将lambda表达式存储在变量中。因此,我将上面的代码修改为以下代码:

BiFunction<Integer, Integer, Integer> myComparator = (x,y) -> x-y;
Map<Integer, String> map3 = new TreeMap<>(myComparator);
Run Code Online (Sandbox Code Playgroud)

但是最后一次尝试没有用!它给出了以下错误:

无法推断TreeMap <>的类型参数

为什么在上一个示例中无法解析类型?

注意:为了确认这不是IDE错误,我使用进行了原始编译javac,但仍给出相同的错误。

Nik*_*las 7

尽管lambda表达式似乎相同,但是BiFunction不是,Comparator因此您不能互换它们。

Comparator<Integer> comparator = (x,y) -> x - y;
Map<Integer, String> map3 = new TreeMap<>(comparator);
Run Code Online (Sandbox Code Playgroud)

让我们更深入地研究这些接口,并使用匿名类实现它们:

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;
    }
};
Run Code Online (Sandbox Code Playgroud)

区别也就是方法的名称。TreeMap期望Comparator在其构造函数中使用,因为其内部实现将compare根据与的合同进行调用Comparator

顺便说一句,BinaryOperator<T>结果也使用相同的lambda表达式。