使用 BiFunction 代替 Comparator 不起作用

Using BiFunction in place of a Comparator does not work

在初始化 TreeMapTreeSet 等集合时,我们可以添加自定义比较器。 代码类似于:

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

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

Map<Integer, String> map2 = new TreeMap<>((x,y) -> x-y);

Java-8 允许您通过 functional interfaces 将 lambda 表达式存储在变量中。所以,我将上面的代码修改为:

BiFunction<Integer, Integer, Integer> myComparator = (x,y) -> x-y;
Map<Integer, String> map3 = new TreeMap<>(myComparator);

但这最后一次尝试没有成功!它给出了以下错误:

Cannot infer type arguments for TreeMap<>

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

注意:为了确认这不是一个 IDE 错误,我使用 javac 执行了原始编译,它仍然给出了同样的错误。

尽管 lambda 表达式看起来相同,但 BiFunction is not the Comparator 因此您不能互换它们。

Comparator<Integer> comparator = (x,y) -> x - y;
Map<Integer, String> map3 = new TreeMap<>(comparator);

让我们深入了解这些接口并使用匿名实现它们 class:

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;
    }
};

区别还在于方法的名称。 TreeMap expects Comparator in its constructor because its internal implementation will call compare according to the contract with Comparator.

顺便说一下,BinaryOperator<T> 也会产生相同的 lambda 表达式。

这仅仅是因为 TreeMap 构造函数需要 Comparator<Integer> 而不是 BiFunction

BiFunction<Integer, Integer, Integer> myComparator = ... 你明确地告诉编译器变量是那个类型。这可以防止编译器推断 TreeMap 构造函数所需的类型。由于 BiFunction 不是 Comparator,也不是它的子类,因此编译器不允许这样做。

因为它需要比较器,而您已经提供了 BiFunction。 来自 Oracle 文档:

@FunctionalInterface
public interface Comparator<T>

A comparison function, which imposes a total ordering on some collection of objects. Comparators can be passed to a sort method (such as Collections.sort or Arrays.sort) to allow precise control over the sort order. Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps), or to provide an ordering for collections of objects that don't have a natural ordering.