lambda表达式
Lambda表达式是Java 8中引入的一种新特性,它允许我们将行为(代码)作为参数传递,并且在需要时进行实现。Lambda表达式可以看作为一个匿名函数,可以像变量一样存储和传递,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),即没有函数名的函数。它可以代替大部分匿名内部类,从而优化我们的代码,提高代码的可读性。
使用条件
若想使用Lambda表达式,那么次接口中必须有且仅有一个需要必须被实现的方法,才能使用Lambda表达式,当然这个接口可以有其他方法,比如用default修饰的方法,或者是静态的方法.(@FunctionalInterface是修饰函数式接口的,要求接口中的抽象方法只有一个。 这个注解往往会和 lambda 表达式一起出现)
函数式接口
对于只有一个抽象方法的接口,需要这种接口对象时,就可以提供一个lambda表达式。这种接口称为函数式接口(functional interface)。
注意:
- 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口;
- 如果我们在某个接口上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接口,这样如果有两个抽象方法,程序编译就会报错的。所以,从某种意义上来说,只要你保证你的接口中只有一个抽象方法,就可以看作函数式接口。
λ表达式基本用法
Lambda表达式:() -> {};
- () :参数列表
- -> : 为 lambda运算符 ,读作(goes to)
- {} :方法体
注意:
- lambda表达式没有参数时,仍要提供空括号,就像无参数方法一样;
- 如果一个lambda表达式只在某些分支返回一个值,而另外的一些分支不返回值,这就不合法例如:
(int x)->{if(x >= 0)return 1; }
就不合法
方法精炼:
- 参数类型可以省略,如果需要省略,每个参数的类型都要省略;
- 参数的小括号里面只有一个参数,那么小括号可以省略;
- 如果方法体当中只有一句代码,那么大括号可以省略;
- 如果方法体中只有一条语句,其是return语句,那么大括号可以省略,且去掉return关键字
public class Main
{
interface Test1{
void Test1();//无参数无返回值
}
interface Test2{
void Test2(int a);//有参数无返回值
}
interface Test3{
String Test3();//无参数有返回值
}
interface Test4{
int Test4(int b);//有参数有返回值
}
public static void main(String[] args) {
Test1 t1 = ()->{
System.out.println("无参数无返回值");
};
t1.Test1();
Test2 t2 = (int a)->{
System.out.println(a);
};
t2.Test2(200);
Test3 t3 = ()->{
return "无参数有返回值";
};
String str=t3.Test3();
System.out.println(str);
Test4 t4 = (int b)->{
if(b >= 0){
return 1;}
else{
return 0;}
};
int i=t4.Test4(4);
System.out.println(i);
}
}
函数引用
lambda表达式是为了简化接口的实现的。所以如果在lambda表达式中需要处理的逻辑比较复杂,⼀般情况会单独的写⼀个方法。在lambda表达式中直接引用这个方法即可。
函数引用:引用⼀个已经存在的方法,使其替代lambda表达式完成接口的实现
注意:
- 在引用的方法后面,不要添加小括号。
- 引用的这个方法,参数(数量、类型)和返回值,必须要跟接口中定义的⼀致
- 静态方法引用:
类名::实例方法名
public class Main {
public static void main(String[] args) {
Test1 t = Test2::Test2;
t.Test1();
}
}
interface Test1{
void Test1();
}
class Test2 {
static void Test2() {
System.out.println("静态方法引用");
}
}
- 非静态方法引用:
对象::非静态方法名
public class Main {
public static void main(String[] args) {
Test1 t = new Test2()::Test2;
t.Test1();
}
}
interface Test1{
void Test1();
}
class Test2 {
public void Test2() {
System.out.println("非静态方法引用");
}
}
- 构造方法引用:
如果某⼀个函数式接口中定义的方法,仅仅是为了得到⼀个类的对象。此时我们就可以使用构造方法的引用,简化这个方法的实现
类名::new