Java如何无中间步骤合并两个Lambda表达式 解决类型推断报错
报错原因与可行实现
这种合并写法完全可以实现,编译报错的核心原因是Java的Lambda表达式没有独立的原生类型,类型推断完全依赖上下文给出的目标类型:
- 拆分两个变量的写法之所以正常,是因为第一段Lambda直接赋值给
Consumer<String[]>类型的sort变量,编译器拿到了明确的目标类型,既能推断入参s是字符串数组,也能顺着推导出Arrays.sort的第二个参数是Comparator<String>,嵌套的比较逻辑Lambda自然不会报错。 - 你写的合并版本里,括号包起来的
s -> Arrays.sort(...)没有任何显式类型标识,编译器解析到这段时还没完成链式调用的全链路类型推导,根本不知道这个Lambda要匹配哪个函数式接口,连带着内部的比较器Lambda也没法做类型校验,才会抛出无法推断类型的错误。
修正后的单变量写法
只需要给第一段Lambda加个显式类型强转,明确它的类型是Consumer<String[]>,就能直接链式调用andThen完成逻辑合并,不需要额外定义中间变量:
public static void main(String[] args) { String[] strings = {"a", "bb", "ccc", "dddd"}; Consumer<String[]> print = ((Consumer<String[]>) s -> Arrays.sort(s, (s1, s2) -> s1.length() - s2.length())) .andThen(s -> System.out.println(Arrays.toString(s))); print.accept(strings); }
上面的代码可以正常编译运行,最终输出按长度升序排序的数组:[a, bb, ccc, dddd]。
内部比较器的参数
s1、s2不需要显式声明String类型,外层类型确定后编译器会自动推断参数类型,要保留显式声明也不会影响运行。当然从工程可读性角度说,拆分中间变量的写法更易维护,这种强转合并的写法更多是满足语法层面的探索需求。
内容的提问来源于stack exchange,提问作者qwertzniki6
相关产品推荐
相关产品推荐

