Java 8中的复杂比较器

3

有人能解释一下以下复杂的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个回答

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

另一方面,当第一个ComparatorComparator.naturalOrder()返回时(它返回一个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);

3
或者只需使用.sorted(Comparator.<String>naturalOrder().thenComparingInt(String::length))... - Holger

2

1
这个回答如何解释为什么一个 sorted 调用通过了编译而另一个没有? - Eran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接