我对以下代码示例提出的问题很少。
class HypotheticComparators {
class Pair<U,T> {
private U left;
private T right;
public U getLeft() {
return left
}
public T getRight() {
return right;
}
}
class User {
private String name;
private Integer age;
public String getName(){
return name;
}
public Integer getAge() {
return age;
}
}
public static void main(String[] args){
List<Pair<LocalDate,LocalDate>> dataIntevals = new ArrayList<>();
//Doesn't Compile
Comparator<Pair<LocalDate,LocalDate>> pairComparator1 = Comparator.comparing(Pair::getLeft).thenComparing(Pair::getRight);
//This Compile
Comparator<Pair<LocalDate,LocalDate>> leftComparator = Comparator.comparing(Pair::getLeft);
Comparator<Pair<LocalDate,LocalDate>> pairComparator2 = leftComparator.thenComparing(Pair::getRight));
//This compile
Comparator<User> userComparator1 = Comparator.comparing(User::getName).thenComparing(User::getAge);
//This also compile
Comparator<User> userNameComparator = Comparator.comparing(User::getName);
Comparator<User> userComparator2 = userNameComparator.thenComparing(User::getAge);
}
}
对于此声明,Comparator<Pair<LocalDate,LocalDate>> pairComparator1 = Comparator.comparing(Pair::getLeft).thenComparing(Pair::getRight);
,我最初的想法是不编译它是themComparaing
无法从Comparator.comparing(Pair::getLeft)
推断出类型。但是,我不相信这个想法,看看Comparator.comparing
和thenComparing
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
default <U extends Comparable<? super U>> Comparator<T> thenComparing(
Function<? super T, ? extends U> keyExtractor)
{
return thenComparing(comparing(keyExtractor));
}
Comparator.comparing(Pair::getLeft)
可以使用T Pair<LocalDate, LocalDate>
进行类型推断,themComparing
也可以使用T作为Pair<LocalDate, LocalDate>
进行类型推断。此外,如果我的想法是正确的,为什么Comparator<User> userNameComparator = Comparator.comparing(User::getName);
可以编译而没有任何问题。我在这里错过了什么吗?
答案 0 :(得分:1)
Java类型提供者不能确定第一个.comparing
将接受与第二个类型相同的类型,因此它猜测第一个方法的类型是{{1} },而Object没有实现Comparable。您可以通过指定方法的泛型类型来解决此问题:
Object, Pair<LocalDate, LocalDate>
答案 1 :(得分:0)
编译器无法在第一种情况下推断出Pair::getLeft
的类型,但在第二种情况下可能是因为它使用变量的类型来推断类型,但是因为您立即致电thenComparing()
,它无法访问此信息。
您可以通过在新行上单独使用Comparator.comparing(Pair::getLeft);
来检查此项,而不将其保存到变量中。编译器将无法推断类型。
这可以通过明确说出Pair<LocalDate,LocalDate>::getLeft
来解决。