一、什么是Lambda表达式
lambda表达式是JAVA8中提供的一种新的特性,它支持JAVA也能进行简单的“函数式编程”。
它是一个匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递)。可以写出更紧凑、更简洁、更灵活的代码。
二、什么时候用Lambda
先提一个lambda表达式的重要特征:Lambda 需要 函数式接口的支持。
什么是 函数式接口呢?
函数式接口(Functional Interface):定义的一个接口,接口里面必须 有且只有一个抽象方法 (JAVA8的接口可以有多个default方法),这样的接口就成为函数式接口。
那么,如果你在某处就真的只需要一个能做一件事情的函数而已,连它叫什么名字都无关紧要。
Lambda 表达式就可以用来做这件事。即 任何函数式接口都可以使用lambda表达式替换。
例如:Comparator、Runnable。
三、Lambda表达式怎么用
1. 表达式写法
Lambda 表达式的语法格式如下:
(parameters) -> expression 或 (parameters) ->{ statements; }
其中,“->”被称为 Lambda 操作符或剪头操作符。
它将 Lambda 分为两个部分:
- 左侧:需要的所有参数;
- 右侧:指定了 Lambda 体,即 Lambda 表达式要执行的功能。
2. 简单例子
让我们来看下面这些例子:
// 返回两数之和
(int x, int y) -> { return x + y; }
// 参数类型也可以省略
(x, y) -> { return x + y; }
// 主体包含了一个语句,不需要 return
(x, y) -> x + y;
// 一个参数无需定义圆括号
c -> { return c.size(); }
// 没有参数,也没有返回值
() -> { System.out.println("Hello World!"); }
3. 特性
lambda表达式有以下重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体包含了一个语句,就不需要 return。
- Lambda 需要 函数式接口的支持。
- lambda 表达式的局部变量可以不用声明为 final,但是不能被修改(即隐性的具有final 的语义)。
4. 化简流程
下面用 Comparator 的例子说明下化简的过程。
/**
* 普通的Comparator
*/
Comparator comparator = new Comparator<User>() {
//使用新的排序规则 根据用户的姓名排序
@Override
public int compare(User a,User b){
return a.getName().compareTo(b.getName());
}
};
Collections.sort(list, comparator);
第一步: 去掉冗余的匿名类:将抽象方法的参数放 -> 左边, 将抽象方法要执行的功能放 -> 右边
Collections.sort(list,(User a, User b) -> a.getName().compareTo(b.getName()));
第二步:使用Comparator里的comparing方法
Collections.sort(list, Comparator.comparing((User p) -> p.getName()));
第三步:类型推导和静态导入
Collections.sort(list, comparing(p -> p.getName()));
第四步:方法引用
Collections.sort(list, comparing(Person::getName));
四、例子
1. 使用lambda表达式实现Runnable
@Test
public void testRunable(){
/**
* 普通的Runnable
*/
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("I am running");
}
};
new Thread(runnable).start();
/**
* 使用lambda后的
*/
new Thread(() -> System.out.println("I am running")).start() ;
}
2. 使用lambda表达式实现Comparator
@Test
public void testComparator(){
/**
* 普通的Comparator
*/
Comparator comparator = new Comparator<User>() {
//使用新的排序规则 根据用户的姓名排序
@Override
public int compare(User a,User b){
return a.getName().compareTo(b.getName());
}
};
/**
* 使用lambda表达式实现
*/
Comparator<User> comparator1 = (a, b) -> a.getName().compareTo(b.getName());
Comparator comparator2 = Comparator.comparing(User::getName);
Collections.sort(list, comparator);
list.forEach(System.out::println);
}
3. 自定义函数式接口,使用Lambda表达式
// 自定义函数式接口
@FunctionalInterface
public interface MyInterface {
void doSomething(String str);
}
@Test
public void testMyInterface(){
/**
* 普通的MyInterface
*/
MyInterface myInterface = new MyInterface() {
@Override
public void doSomething(String str) {
System.out.println("hello " + str);
}
};
/**
* 使用Lambda表达式
*/
MyInterface myInterface1 = (c) ->System.out.println("hello " + c);
}
4. 使用lambda表达式完成for-each循环操作
@Test
public void testForEach(){
/**
* 原本的for-each循环写做法
*/
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
/**
* 使用lambda表达式后的写法
*/
list.forEach(System.out::println);
}
五、参考
- JAVA8之lambda表达式详解,及stream中的lambd
https://blog.csdn.net/jinzhencs/article/details/50748202