键入变量,方法内联和"lambda表达式中的错误返回类型"

Ada*_*ion 4 java lambda java-8

我正在使用新的Java 8功能:接口中的lambda,default和static方法.

这段代码工作正常:

@FunctionalInterface
interface Comparator<T> {
    int compare(T a, T b);

    static <T> Comparator<T> comparing(Function<T, Comparable> f) {
        return (a, b) -> f.apply(a).compareTo(f.apply(b));
    }

    default Comparator<T> thenComparing(Comparator<T> comp) {
        return (a, b) -> compare(a, b) == 0 ? comp.compare(a, b) : compare(a, b);
    }

    default Comparator<T> thenComparing(Function<T, Comparable> f) {
        return thenComparing(comparing(f));
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我内联thenComparing(Comparator<T> comp)到Hower thenComparing(Function<T, Comparable> f):

@FunctionalInterface
interface Comparator<T> {
    int compare(T a, T b);

    static <T> Comparator<T> comparing(Function<T, Comparable> f) {
        return (a, b) -> f.apply(a).compareTo(f.apply(b));
    }

    default Comparator<T> thenComparing(Function<T, Comparable> f) {
        return (a, b) -> compare(a, b) == 0 ? comparing(f) : compare(a, b);
    }
}
Run Code Online (Sandbox Code Playgroud)

编译失败:

error: incompatible types: bad return type in lambda expression
  return (a, b) -> compare(a, b) == 0 ? comparing(f) : compare(a, b);
                                                       ^
bad type in conditional expression
  no instance(s) of type variable(s) T exist so that Comparator<T> conforms to int
where T is a type-variable:
  T extends Object declared in method <T>comparing(Function<T,Comparable>)
Run Code Online (Sandbox Code Playgroud)

为什么?


另一个版本没有Comparable用作原始类型:

@FunctionalInterface
interface Comparator<T> {
    int compare(T a, T b);

    static <T, U extends Comparable<U>> Comparator<T> comparing(Function<T, U> f) {
        return (a, b) -> f.apply(a).compareTo(f.apply(b));
    }

    default Comparator<T> thenComparing(Comparator<T> comp) {
        return (a, b) -> compare(a, b) == 0 ? comp.compare(a, b) : compare(a, b);
    }

    default <V extends Comparable<V>> Comparator<T> thenComparing(Function<T, V> f) {
        return thenComparing(comparing(f));
    }
}
Run Code Online (Sandbox Code Playgroud)

Tun*_*aki 5

这不起作用,因为:

  • comparing(f) 返回一个 Comparator<T>
  • compare(a, b) 返回一个 int

因此类型在三元表达式中不兼容:

(a, b) -> compare(a, b) == 0 ? comparing(f) : compare(a, b);
                               ^----------^   ^-----------^
                               Comparator<T>       int
Run Code Online (Sandbox Code Playgroud)

你想要的是调用.compare(a, b)下一个比较比较器,如果第一个返回相同的项目:

default Comparator<T> thenComparing(Function<T, Comparable> f) {
    return (a, b) -> compare(a, b) == 0 ? comparing(f).compare(a, b) : compare(a, b);
}
Run Code Online (Sandbox Code Playgroud)

作为旁注,您使用的Comparable是原始类型.不要那样做.

  • @sedulam不,因为比较器是`(a,b) - > someint` (2认同)