我使用Comparator
对流进行排序,而且我遇到了一些我不理解的编译错误。
我们说我有以下课程:
class Base {
private LocalDate date;
public LocalDate getDate() { return date; }
...
}
class Sub extends Base { ... }
我创建两个比较器,按日期排序Sub
,一个按自然顺序排序,一个按相反顺序排序。以下代码编译:
Comparator<Sub> fwd = Comparator.comparing(Sub::getStartDate);
Comparator<Sub> rev1 = Comparator.comparing(Sub::getStartDate).reversed();
Comparator<Sub> rev2 = fwd.reversed();
意识到在getDate()
上定义了Base
,我想我会尝试以下方法:
Comparator<Sub> fwd = Comparator.comparing(Base::getStartDate);
Comparator<Sub> rev1 = Comparator.comparing(Base::getStartDate).reversed(); // Compiler error
Comparator<Sub> rev2 = fwd.reversed(); // OK
令人惊讶(对我而言),rev2
的代码编译正常,而rev1
的代码产生以下错误:
Cannot infer type argument(s) for <T, U> comparing(Function<? super T, ? extends U>)
The type Base does not define getStartDate(Object) that is applicable here
为什么我会收到这些编译器错误?为什么在从rev2
构建fwd
时可以有效地规避它们?
(我正在使用Eclipse Oxygen.3a(4.7.3)和Java v1.8.0_162,如果相关的话。)
答案 0 :(得分:2)
正如answer所述,目标类型因调用reversed()
而中断:
Comparator<Sub> rev1 =
Comparator.comparing(Base::getStartDate)
.reversed(); // Compiler error - incompatible types
在这种情况下,编译器会推断出以下类型参数:
Comparator<Sub> rev1 =
Comparator.<Base, LocalDate>comparing(Base::getStartDate)
.reversed(); // Compiler error - incompatible types
要消除错误,您可以明确提供类型参数:
Comparator<Sub> rev1 =
Comparator.<Sub, LocalDate>comparing(Base::getStartDate)
.reversed(); // Okay, no problem
或使用双参数Comparator.comparing()
:
Comparator<Sub> rev1 =
Comparator.comparing(Base::getStartDate, Comparator.reverseOrder());