Java 8 溪流:;无法将比较器转换为int";使用方法引用时

Java 8 溪流:;无法将比较器转换为int";使用方法引用时,java-8,java-stream,Java 8,Java Stream,假设我有一个字符串流: Stream<String> stream = Stream.of("c","a","b"); 但使用替代语法不会: stream.sorted(Comparator::reverseOrder) ^ Bad return type in method reference: cannot convert Comparator<T> to int 一本书解释说: 比较器是一个功能接口。这意味着

假设我有一个字符串流:

Stream<String> stream = Stream.of("c","a","b");
但使用替代语法不会:

stream.sorted(Comparator::reverseOrder)
                        ^
   Bad return type in method reference: cannot convert Comparator<T> to int
一本书解释说:

比较器是一个功能接口。这意味着我们可以使用 方法引用或lambda来实现它。比较器接口 实现一个方法,该方法接受两个字符串参数并返回 int。但是,Comparator::reverseOrder不能做到这一点。这是一个 引用一个函数,该函数接受零个参数并返回一个 比较器。这与接口不兼容。这意味着 我们必须使用方法,而不是方法引用


但是我不明白。

当一个比较器在java中工作时,它比较两个值并返回-1表示较小值,0表示相等值,1表示较大值。方法引用正在返回一个类型比较器,但是集合逆序方法需要一个int来知道被比较的元素是更小还是更大,以便进行排序

例如,当它比较一个数组[c,a,b,c] 首先,它将c与a进行比较(默认情况下,它使用自然顺序进行比较),因此它将返回1,这意味着c大于a。 当它将a与b进行比较时,它将返回a-1,这意味着a小于b


使用这些返回值是比较器使用接口中提供的默认.sort()进行排序的方式

如果函数接口中的方法具有类型参数,则不能对函数接口使用lambda表达式

请参考此答案-

要进行验证,请尝试以下操作-

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));
类MyComparator实现比较器{
@凌驾
公共整数比较(字符串o1、字符串o2){
返回o1。与(o2)相比;
}
}
MyComparator MyComparator=新的MyComparator();
stream.sorted(myComparator::compare).forEach(s->System.out.println(s));

这是因为在这种情况下,
MyComparator的
compare
方法知道类型-
String

简单地说,您需要一个
比较器,而不是一个返回比较器的方法的引用。方法引用将与任何匹配
比较器的签名的方法一起工作

实际的替代方案

stream.sorted(Comparator.reverseOrder())

stream.sorted((o1,o2)->Comparator.reverseOrder().compare(o1,o2));

由于
排序的
方法接受一个
比较器,因此方法引用等价于Lambda表达式,该表达式只能在需要
功能接口时使用
排序
不需要
功能接口
,它需要一个普通的'ol
比较器
。如果
sorted
的签名如下所示,那么方法参考将起作用:
sorted(供应商我不理解您的混淆,reverseOrder()是一种返回具有某种行为的比较器的方法。
sorted
需要一个这样的比较器,而不是一个方法引用来获取某个比较器。-
Comparator::reverseOrder
不是
Comparator.reverseOrder()的“替代语法”
@luk2302上面的评论似乎就是您要寻找的答案。
Comparator.reverseOrder()
是一个方法调用,它返回一个
比较器
比较器::reverseOrder
是一个函数的引用。
比较器
本身就是一个返回
int
的函数。因此,错误表明它看到了一个
比较器
(通过调用
比较器::reverseOrder
返回)它希望看到一个
int
(通过调用
comparator.reverseOrder()创建的比较器返回)
@luk2302我会把你的评论作为答案发布。我很乐意接受一个混合/合并了luk2302和mystackrunnethover的答案。带有lambda的行不可编译。你能修复吗?@Andrey是的,这一次吃了一个点,而不是为了看看Java在没有显式
的情况下无法推断类型
字符串
,虽然我们在一条流上运行。哦,好吧:)谢谢,upvoting提供了“自己试试这个”的例子upvoting以及“如果签名是”。谢谢。对我来说,完整和详尽的答案分为Grzegorz的答案、你的答案和darcula的答案。
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));
stream.sorted(Comparator.reverseOrder())
stream.sorted((o1, o2) -> Comparator.<String>reverseOrder().compare(o1, o2));