Java 8 Stream中Comparator.comparing不用方法引用为何失效?
为什么不能直接用
Animal.getName()调用Comparator.comparing? 嘿,我来拆解一下你遇到的问题,先把两段代码摆出来更清楚:
可正常运行的代码
List<Animal> animals = this.service.findAll(); animals = animals.stream() .sorted(Comparator.comparing(Animal::getName)) .collect(Collectors.toList()); // working
无法运行的代码
List<Animal> animals = this.service.findAll(); animals = animals.stream() .sorted(Comparator.comparing(Animal.getName()).collect(Collectors.toList()); // Not working
核心问题:参数类型不匹配 + 语法错误
首先说最关键的点:Comparator.comparing()方法需要的参数是一个**Function<T, U>类型的函数式接口**,简单说就是一个能把Animal对象转换成某个可比较类型(比如你的getName()返回的String)的逻辑。
- 你正确代码里的
Animal::getName是方法引用,它本质上相当于一个lambda表达式animal -> animal.getName(),刚好符合Function<Animal, String>的要求:接收一个Animal,返回它的名字。 - 而错误代码里的
Animal.getName()是直接调用了getName方法——如果getName()是实例方法,这里甚至会编译报错(因为你没有通过Animal实例调用);就算它是静态方法,这里返回的是一个String对象,而comparing()要的是Function,不是String,类型完全不匹配,编译器根本不知道你要怎么把Animal转换成用来排序的键。
另外你的错误代码还有个语法小问题:sorted()的括号没闭合就直接写.collect()了,这也会导致编译失败,但这是次要问题,核心还是参数传递错了。
总结一下
Comparator.comparing()需要的是“如何从对象中提取排序键”的逻辑,而不是直接给它一个排序键的值。方法引用(或者lambda)是把提取逻辑传递给它,而直接调用方法是把提取后的结果传进去,这完全是两回事哦~
内容的提问来源于stack exchange,提问作者AConsumer
相关产品推荐
相关产品推荐

