Lambda表达式和函数式接口

Lambda表达式和函数式接口 Lambda表达式语法的本质上就是一种表达式,而非对象。 Lambda表达式的返回值会被自动推导。如果参数被省略,那么也会尝试自动推导。 函数式接口(Functional Interface)指的是只有一个抽象方法的接口。(可以有一些非抽象方法,如重写或默认) Lambda表达式是被设计为快速地转换为函数式接口的实例。程序员不用手动初始化函数式接口的实例了,这些对象和类的管理由编译器处理。 方法引用和构造器引用 方法引用(Method Reference)是一种简便方式,可以在只想调用一个方法而不做其他操作时,直接使用某个方法的逻辑。 原理类似于Lambda表达式,编译器自动为你创建函数式接口的实例。 例如: var timer = new Timer(1000, System.out::println) 要注意方法重载的选择受函数式接口的签名影响。 方法引用支持三种语法: object::instanceMethod:lambda表达式的参数列表原样传送到这个对象的这个方法的参数中。 Class::instanceMethod:lambda表达式的第一个参数成为方法的隐式参数,也就是说:String::compareToIgnoreCase, 等价于(a, b) -> a.compareToIgnoreCase(b) Class::staticMethod: 所有参数传递到静态方法。 构造器引用 格式:Class::new 解决的问题:将类型被擦除的数组重新构建为特定对象数组。 例如:Person[] people = stream.toArray(Person::new) 变量作用域和闭包 Lambda表达式由三部分组成: 一个代码块 参数 自由变量的值,这里是指非参数切不在代码块内被定义的变量 当lambda体使用了外部的变量时,称为这个变量被捕获(captured) 捕获capture自由变量的代码块称为闭包closure。lambda表达式就是闭包。 捕获变量的限制(这是为了并发安全考虑): 在lambda体中,不可以改变捕获的变量。 捕获的变量不可能在外部改变 捕获的变量必须是事实最终变量(efectively final)。aka,变量初始化后不会再被赋新值。 lambda表达式的体与它的上一层嵌套块有相同的作用域。也就是说,lambda表达式不新建作用域,参数和内部变量不能和上一层重名。 这也是为什么你可以直接使用外层方法的this Lambda表达式的应用 《Core Java 中文版》6.2.7 为什么要使用Lambda表达式?一个重要原因是支持代码的延迟执行(deferred execution) 换句话说,如果不需要延迟执行,那么很可能不需要lambda表达式。 在一个单独的线程运行代码 在算法的适当位置运行代码(比如排序的比较操作) 发生某种事件时才触发代码 只在必要时才执行代码 常用的函数式接口: Runnable Supplier<T> Comsumer<T> BiConsumer<T, U> Function<T,R> BiFunction<T, U, R> UnaryOperator<T> BynaryOperator<T> Predicate<T> BiPredicator<T, U> 除了Runnable,它们都在java.util.function里面 ...

July 17, 2026

Hello World

这是我的第一篇博客!

July 16, 2026