假设我有一个字符串流:
Stream<String> stream = Stream.of("c","a","b");
这样可行:
stream.sorted(Comparator.reverseOrder())
但是使用替代语法不会:
stream.sorted(Comparator::reverseOrder)
^
Bad return type in method reference: cannot convert Comparator<T> to int
当我在我的IDE中按Ctrl +左键单击时,我都会转到同一个静态方法,在Comparator
类中返回一个Comparator:
public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
return Collections.reverseOrder();
}
一本书解释说:
比较器是一个功能界面。这意味着我们可以使用 方法引用或lambda来实现它。比较器接口 实现一个方法,它接受两个String参数并返回一个 int。但是,Comparator :: reverseOrder不会这样做。它是一个 引用一个接受零参数并返回a的函数 比较器。这与界面不兼容。这意味着 我们必须使用方法而不是方法参考。
但我不明白。
答案 0 :(得分:2)
简而言之,您需要一个Comparator
而不是对返回一个方法的引用。方法引用适用于任何与Comparator
签名匹配的方法。
的实际替代方案
stream.sorted(Comparator.reverseOrder())
是
stream.sorted((o1, o2) -> Comparator.<String>reverseOrder().compare(o1, o2));
由于sorted
方法接受Comparator<? super T>
个实例,Comparator::reverseOrder
无法在此使用,因为它是Supplier<Comparator<String>>
的实例。< / p>
答案 1 :(得分:2)
方法引用等同于只能在需要FunctionalInterface
的情况下使用的Lambda表达式。 sorted
并不期望FunctionalInterface
,它需要简单的Comparator
。如果sorted
的签名如下,则方法参考将起作用:<T> sorted(Supplier<? extends Comparator<T>> s)
。
答案 2 :(得分:1)
如果功能接口中的方法具有类型参数,则不能将lambda表达式用于功能接口。
参考这个答案 - https://stackoverflow.com/a/22588738/8202194
要验证,请尝试此操作 -
class MyComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
}
MyComparator myComparator = new MyComparator();
stream.sorted(myComparator::compare).forEach(s ->System.out.println(s));
这是有效的,因为compare
的{{1}}方法在这种情况下知道类型 - MyComparator
。
答案 3 :(得分:0)
当比较器在java中工作时,它会比较两个值并返回-1表示较小,0表示相等,1表示较大。方法引用返回类型Comparator,但Collections逆序方法需要一个int来知道被比较的元素是小还是大,以便它可以排序。
例如,它比较一个数组[c,a,b,c] 首先它将c与a进行比较(默认情况下它使用自然顺序进行比较),因此它将返回1,这意味着c大于a。 当它比较a到b时,它将返回-1,这意味着a小于b
使用这些返回值是比较器如何使用接口中提供的默认.sort()进行排序