Java中Comparator.comparing结合reversed时Lambda写法报错原因咨询
先直接说核心问题:你的Lambda写法报错是因为编译器类型推断失败,下面具体拆解两种写法的区别和报错根源。
方法引用写法为什么正常?
Comparator.comparing(Movie::getTitle).reversed()
Movie::getTitle是绑定到Movie类的方法引用,编译器能直接识别出这个方法引用对应的Function输入类型是Movie,输出类型是getTitle的返回值类型(比如String)。
结合Comparator.comparing的方法签名:static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor),编译器可以明确推断出泛型参数T=Movie,U=String,后续调用reversed()时,整个Comparator的类型是确定的,自然不会出错。
Lambda写法为什么报错?
Comparator.comparing(m -> m.getTitle()).reversed()
当你写m -> m.getTitle()时,编译器需要从上下文推断m的类型,但链式调用里的reversed()打断了推断流程:编译器在处理comparing(m -> m.getTitle())时,还没来得及从后续的sorted方法(需要Comparator<Movie>)获取类型信息,只能默认把m推断成Object类型——而Object没有getTitle()方法,所以就出现了“Cannot resolve method 'getTitle' in 'Object'”的错误。
简单说:Lambda的类型推断依赖完整的上下文,但链式调用的reversed()让编译器提前“断片”,没法正确识别m的类型;而方法引用因为和Movie类强绑定,类型信息更明确,不受链式调用影响。
Lambda写法的修复方案
两种简单的修复方式:
显式指定Lambda参数类型:
Stream<Movie> sortedMovies2 = movies.stream() .sorted(Comparator.comparing((Movie m) -> m.getTitle()).reversed());直接给
m加上Movie类型声明,强制编译器识别输入类型,就能找到getTitle()方法。拆分链式调用:
Comparator<Movie> titleComparator = Comparator.comparing(m -> m.getTitle()); Stream<Movie> sortedMovies2 = movies.stream().sorted(titleComparator.reversed());先把
comparing的结果赋值给明确泛型类型的变量,编译器能正确推断m是Movie,再调用reversed()就没问题了。
内容的提问来源于stack exchange,提问作者user27995911

