java 8 中的复数比较器

Complex Comparators in java 8

有人可以解释以下复杂 Comparator 变体之间的区别吗?

List<String> listOfStrings = Arrays.asList("algo", "test", "is", "a", "common");

listOfStrings.stream()
             .sorted(Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder()))
             .sorted(Comparator.naturalOrder().thenComparing(Comparator.comparingInt(String::length))
             .forEach(System.out::println);

为什么第一次调用sorted可以,而第二次却连编译都编译不了?

  1. comparingInt(ToIntFunction keyExtractor)

接受从类型 T 中提取 int 排序键的函数,以及 returns 通过该排序键进行比较的比较器。

  1. 自然顺序()

Returns 以自然顺序比较 Comparable 对象的比较器。

您可以从那里检查自然顺序; difference between natural ordering and total ordering

比较器API; https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#naturalOrder--

编译器知道 Comparator.comparingInt(String::length) returns 一个 Comparator<String> (因为你传递一个 ToIntFunction<String> 给它),因此期望第二个 Comparator , 传递给 thenComparing 是一个 Comparator<String>,所以它可以推断 Comparator.naturalOrder() 返回的 Comparator 的类型是一个 Comparator<String>.

另一方面,当第一个ComparatorComparator.naturalOrder()返回时(which returns a Comparator<T>),编译器不知道是哪个类型的Comparator 期望 thenComparing 的参数,因此它拒绝传递给它的 Comparator<String>

如果您显式声明 Comparator.naturalOrder() 返回的 Comparator 的类型,则可以避免此错误:

Comparator<String> comp = Comparator.naturalOrder();
listOfStrings.stream()
             .sorted(comp.thenComparing(Comparator.comparingInt(String::length)))
             .forEach(System.out::println);