Java 8中的复杂比较器

时间:2018-10-09 07:07:20

标签: java java-8 java-stream comparator type-inference

有人可以解释复杂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可以,而第二个甚至不能编译?

2 个答案:

答案 0 :(得分:5)

编译器知道Comparator.comparingInt(String::length)返回一个Comparator<String>(因为您正在向其传递ToIntFunction<String>),因此期望第二个Comparator传递给{{1 }}设为thenComparing,因此可以推断Comparator<String>返回的Comparator的类型为Comparator.naturalOrder()

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

如果您明确声明Comparator<String>返回的Comparator的类型,则可以避免此错误:

Comparator.naturalOrder()

答案 1 :(得分:2)

  1. comparingInt(ToIntFunction keyExtractor)

接受一个函数,该函数从类型T中提取一个int排序键,然后返回一个与该排序键进行比较的Comparator。

  1. naturalOrder()

返回一个比较器,该比较器以自然顺序比较可比较对象。

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

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