Lambda表达式
什么是Lambda表达式
简单来说:可以看成是对匿名内部类的简写,使用Lambda表达式时,接口必须是函数式接口。
Lambda表达式基本语法
*基本语法*:
<函数式接口> <变量名> = (参数1,参数2...) -> {
//方法体
}
*特点说明:*
(参数1,参数2…)表示参数列表;->表示连接符;{}内部是方法体
1、=右边的类型会根据左边的函数式接口类型自动推断;
2、如果形参列表为空,只需保留();
3、如果形参只有1个,()可以省略,只需要参数的名称即可;
4、如果执行语句只有1句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有1句;
5、形参列表的数据类型会自动推断;
6、lambda不会生成一个单独的内部类文件;
7、lambda表达式若访问了局部变量,则局部变量必须是final的,若是局部变量没有加final关键字,系统会自动添加,此后在修改该局部变量,会报错;
一个案例学会Lambda表达式
需求:实现两数相加
接口定义:
public interface MyInterface {
Integer sum(Integer num1,Integer num2);
}
普通实现类
public class MyInterfaceTest implements MyInterface {
@Override
public Integer sum(Integer num1, Integer num2) {
return num1+num2;
}
public static void main(String[] args) {//普通写法
MyInterfaceTest myInterfaceTest=new MyInterfaceTest();
int i=myInterfaceTest.sum(10,20);
System.out.println(i);
}
}
运行结果
匿名内部类实现
如若读者对匿名内部类不太熟悉,可看笔者之前的文章。
public class MyInterfaceTest implements MyInterface {
@Override
public Integer sum(Integer num1, Integer num2) {
return num1+num2;
}
public static void main(String[] args) {//匿名内部类写法
MyInterface myInterface=new MyInterface(){
@Override
public Integer sum(Integer num1, Integer num2) {
return num1+num2;
}
};
System.out.println(myInterface.sum(10,20));
}
}
运行结果
Lambda表达式写法1
public class MyInterfaceTest implements MyInterface {
@Override
public Integer sum(Integer num1, Integer num2) {
return num1+num2;
}
public static void main(String[] args) {//lambda表达式写法1,省一个{}
MyInterface myInterface=(Integer num1, Integer num2)-> {
return num1+num2;
};
System.out.println(myInterface.sum(10,20));
}
}
这里我们可以看出,Lambda方法一可以看出,第一种Lambda方法是省略了实例化的对象名,等号之后直接跟方法参数,以及尖括号和方法括号,方法括号内写方法的执行内容。
运行结果
Lambda表达式写法2
public class MyInterfaceTest implements MyInterface {
@Override
public Integer sum(Integer num1, Integer num2) {
return num1+num2;
}
public static void main(String[] args) {//lambda表达式写法2
MyInterface myInterface=(Integer num1, Integer num2)->num1+num2;
System.out.println(myInterface.sum(10,20));
}
}
这里我们可以看出写法2与写法1相比,将return有给省略了,显得代码更加的简洁。
运行结果
Lambda相关语法详解
特点说明:
普通方法的写法
1、=右边的类型会根据左边的函数式接口类型自动推断;
2、如果形参列表为空,只需保留();
3、如果形参只有1个,()可以省略,只需要参数的名称即可;
4、如果执行语句只有1句,且无返回值,{}可以省略,
若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有1句;
5、形参列表的数据类型会自动推断;
6、lambda不会生成一个单独的内部类文件;
7、lambda表达式若访问了局部变量,则局部变量必须是final的,
若是局部变量没有加final关键字,系统会自动添加,此后在修改该局部变量,会报错;
静态方法引用【掌握】
语法 : 类名::静态方法名
注意事项:
被引用的静态方法参数列表和函数式接口中抽象方法的参数一致!!
接口的抽象方法没有返回值,引用的静态方法可以有返回值也可以没有
接口的抽象方法有返回值,引用的静态方法必须有相同类型的返回值!!
由于满足抽象参数列表与引用参数列表相同,所以可以写成静态方法引用的格式
实例方法引用【掌握】
语法 : 对象名::非静态方法名
注意事项:
被引用的实例方法参数列表和函数式接口中抽象方法的参数一致!!
接口的抽象方法没有返回值,引用的实例方法可以有返回值也可以没有
接口的抽象方法有返回值,引用的实例方法必须有相同类型的返回值!
构造方法引用【掌握】
语法 :类名::new
注意事项:
被构造方法与函数式接口的抽象方法参数列表一致
Lambda表达式方法引用
调用静态方法
需求:实现类型转换
接口
public interface MyInterface4 {
int transfer(String str);
}
匿名内部类
public class MyInterface4Test implements MyInterface4 {
@Override
public int transfer(String str){
return Integer.parseInt(str);
}
public static void main(String[] args) {
MyInterface4 myInterface4=new MyInterface4() {
@Override
public int transfer(String str) {
return Integer.parseInt(str);
}
};
System.out.println(myInterface4.transfer("12"));
}
运行结果
Lambda表达式方法1
public class MyInterface4Test implements MyInterface4 {
@Override
public int transfer(String str){
return Integer.parseInt(str);
}
public static void main(String[] args) {
MyInterface4 myInterface4=str->Integer.parseInt(str);//简单lambda表达式
System.out.println(myInterface4.transfer("2"));
}
运行结果
Lambda表达式方法2
public class MyInterface4Test implements MyInterface4 {
@Override
public int transfer(String str){
return Integer.parseInt(str);
}
public static void main(String[] args) {
MyInterface4 myInterface4=Integer::parseInt;//去掉了->,直接就是类型和方法
System.out.println(myInterface4.transfer("67"));
}
运行结果
调用实例方法
匿名内部类
public class MyInterface4Test implements MyInterface4 {
@Override
public int transfer(String str){
return Integer.parseInt(str);
}
public static void main(String[] args) {//实例方法调用
String str="hello world!";
Function<String,Boolean> func1=new Function<String, Boolean>() {
@Override
public Boolean apply(String s) {
return s.endsWith("123");//判断字符是否以123结尾
}
};
boolean test=test(func1,"123");
System.out.println(test);
}
public static boolean test(Function<String,Boolean> f,String str){
return f.apply(str);
}
运行结果
Lambda表达式方法1
public class MyInterface4Test implements MyInterface4 {
@Override
public int transfer(String str){
return Integer.parseInt(str);
}
public static void main(String[] args) {//常规lambda表达式
String str="hello world";
Function<String,Boolean> func2=t-> str.startsWith("hello");
boolean test=test(func2,str);
System.out.println(test);
}
public static boolean test(Function<String,Boolean>f,String string){
return f.apply(string);
}
运行结果(判断字符串是否以hello开头)
Lambda表达式放法2
public class MyInterface4Test implements MyInterface4 {
@Override
public int transfer(String str){
return Integer.parseInt(str);
}
public static void main(String[] args) {//lambda表达式简写
String str="hello world";
Function<String,Boolean> func3= str::endsWith;
boolean test=test(func3,str);
System.out.println(test);
}
public static boolean test(Function<String,Boolean> f,String str){
return f.apply("world");//是否以world结尾
}
}
运行结果(判断是否以world结尾)
写在最后
Lambda表达式主要是为了简化代码,提升编码效率。对于开发人员的要求能够看得懂Lambda表达式,能够用为锦上添花,不会用也无伤大雅。但一定要能够读懂,不然后续接收模块开发时,看不懂上一波人写的代码就会很影响整体项目进度。Lambda表达式多写多练即可,没有什么技巧,只能靠熟练。笔者小,中,大厂均匀面试经历,每日分享JAVA全栈相关知识,希望能与大家共同进步。