概念
Lambda 表达式(lambda expression)是一个匿名函数,是简化接口实现的
Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁
使用lamdba的前提条件是函数式接口
- 函数是接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法(实现类必须要重写的方法),但是可以有多个非抽象方法的接口。
-
函数式接口都可以使用lamdba表示
-
定义函数式接口,使用@FunctionalInterface(会校验接口是否是函数式接口) 注解
-
定义函数式接口如下:
/**
* @author liouwb
*/
@FunctionalInterface
public interface MyFun {
void sayHello(String param);
}
- 上面的函数式接口使用lamdba表示为:
/**
* @author liouwb
*/
public class Test {
public static void main(String[] args) {
MyFun fun = param -> System.out.println(param);
fun.sayHello("hello world");
}
}
- 执行结果
hello world
java内置函数式接口
lamdba语法
- 单个参数
(参数)->{方法体}
参数类型可以省略,如果方法体只有一行,大括号也可以省略
param->expression
- 参数要求参数类型、数量和实现接口中的参数类型和数量保持一致
->
分隔参数与方法体- 在写lamdba的由于是匿名函数,可以不用关心方法名和返回值类型
- 如果接口中定义的有返回值,则实现的时候也要有返回值
lamdba语法进阶:函数引用(方法调用)
- 引用一个已经存在的方法,来代替lamdba所要完成的实现
静态方法引用
- 使用类名两个冒号::方法名调用
- 类::静态方法(方法不要小括号)
/**
* @author liouwb
*/
public class LamdbaTest {
public static void main(String[] args) {
// 普通lamdba
Fun1 f=(a,b)->a+b;
System.out.println(f.sum(1, 2));
// 函数引用
Fun1 f2=LamdbaTest::sum;
System.out.println(f2.sum(2, 3));
}
/**
* 定义个一有两个参数,有返回值的函数式接口
*/
private static interface Fun1 {
int sum(int a, int b);
}
/**
* 一个两个数相加的方法
* @return
*/
private static int sum(int a,int b){
return a+b;
}
}
- 结果输出
3
5
Process finished with exit code 0
非静态方法
- new class():: 方法
public static void main(String[] args) {
// 非静态方法引用
// 函数引用
Fun1 f3=new LamdbaTest()::sum2;
System.out.println(f3.sum(2, 3));
}
/**
* 定义个一有两个参数,有返回值的函数式接口
*/
private static interface Fun1 {
int sum(int a, int b);
}
/**
* 一个两个数相加的方法 非静态方法
* @return
*/
int sum2(int a,int b){
return a+b;
}
构造方法引用
- 类名::new
/**
* @author liouwb
*/
public class LamdbaTest2 {
public static void main(String[] args) {
// 无参
PersonFun p=Person::new;
p.getPerson();
// 有参
PersonFun2 p2=Person::new;
p2.getPerson("张三",18);
}
/**
* 函数式接口无参
*/
@FunctionalInterface
private interface PersonFun{
Person getPerson();
}
/**
* 函数式接口有参
*/
@FunctionalInterface
private interface PersonFun2{
Person getPerson(String name,int age);
}
/**
* 定义person对象有两个属性
* 两个构造函数
*/
private static class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("有参构造方法:姓名:"+name);
}
public Person() {
System.out.println("无参构造");
}
}
}
- 执行结果
无参构造
有参构造方法:姓名:张三
Process finished with exit code 0
特殊方法引用
/**
* @author liouwb
*/
public class LamdbaTest3 {
public static void main(String[] args) {
// 初始化Person对象
Person p=new Person();
p.setName("张三");
p.setAge(20);
// 1.普通lamdba
PersonFun fun2=(person, age) -> person.setAge(age);
fun2.setAge(p,20);
System.out.println("普通lamdba,年龄:"+ p.getAge());
// 第一个参数是方法调用者,其他参数是方法的参数(参数也可以是多个) 可以简化为
PersonFun fun3= Person::setAge;
fun3.setAge(p,30);
System.out.println("简化后,年龄:"+p.getAge());
// 2.接口的实现,刚好是参数的一个方法 也可以简化
PersonFun1 fun1=person->person.sayHello();
PersonFun1 f=Person::sayHello;
}
/**
* 函数式接口
*/
@FunctionalInterface
private interface PersonFun1{
void sayHello(Person person);
}
/**
* 函数式接口
*/
@FunctionalInterface
private interface PersonFun{
void setAge(Person person, int age);
}
/**
* 定义person对象有两个属性
* 两个构造函数
*/
private static class Person{
String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
void sayHello(){
System.out.println("hello");
}
}
}
- 输出结果
普通lamdba,年龄:20
简化后,年龄:30
hello
Process finished with exit code 0