lambda表达式是什么?
lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。也被称为闭包。
名字的由来:
一个逻辑学家Alonzo Church用希腊字母lambda(λ)来表示参数,因此后来就把带参数的表达式称为lambda表达式。
Java为什么要引入lambda表达式?
java是一门面向对象的语言,要想在java中传递一个代码段通常需要构造一个对象,这个对象的类需要有一个方法包含所需的代码段。
在java8中,设计者们引入了lambda表达式来支持函数式编程,从而让一些代码变得更加简洁和紧凑,以及实现延迟执行。
lambda表达式的使用场景:
- 想在一个单独的线程中运行代码
- 多次运行代码
- 在算法的适当位置运行代码,比如排序中的比较操作
- 发生某些情况时运行代码,比如点击了一个按钮
lambda表达式的语法
标准的格式是:
(参数) -> {代码}
- 如果lambda表达式只有一个参数,而且这个参数的类型可以推导得出,可以省略()
- 如果lambda表达式没有参赛,则必须要提供空的()
Timer timer = new Timer(1000, event -> System.out.println("The time is "+ new Date()); timer.start();
函数式接口
使用lambda表达式,离不开函数式接口。
函数式接口:只有一个抽象方法的接口。
例如interface Comparator<T>就是一个函数式接口,它只有一个抽象的方法:
(Comparator为什么函数式接口:Comparator为何是函数式接口?_皮皮蟹01的博客-CSDN博客)
int compare(T o1, T o2);
Arrays.sort(words, (first,second) -> first.length() - second.length());
在底层,Arrays.sort会接收实现了Comparator<String>的某个类的对象,在这个对象调用compare方法时就会执行lambda表达式的体。
方法引用
当lambda表达式的体只调用一个方法而不做其他操作时,可以把lambda表达式重写为方法引用。
方法引用的3种写法:
object::instanceMethod | 等价于向方法传递参赛的lambda表达式: x -> System.out.println(x) |
Class::instanceMethod | 第一个残暑会成为方法的隐式参数: (x,y) -> x.compareToIgnoreCase(y) |
Class::staticMethod | 所有参赛都传到静态方法里: (x,y) -> Math.pow(x,y) |
变量作用域
lambda表达式可以捕获外围作用域中变量的值,但有一个重要的限制:只能引用不会改变的变量。
如果在lambda表达式中更改变量,并发执行多个动作时就会不安全。
public static void count(int start, int delay){ ActionListener listener = event -> { start --; // ERROR } }
lambda表达式中使用this关键字,是指创建这个表达式的方法的this参数。
处理lambda表达式
例如,想重复执行一段代码10次:
public static void main(String[] args) { repeat(10, i -> System.out.println("count: " + (9 - i))); } public static void repeat(int n, IntConsumer action) { for (int i = 0; i < n; i++) { // 调用下面的方法时就会执行lambda表达式的体 // 循环10次,就调用10次下面的方法,体也就被执行了10次 action.accept(i); } }
笔记内容整理自《java核心技术》