Lambda
1、函数式编程思想
1.其作用是尽量忽略面向对象的复杂语法,是代码看着更简洁。
2、具体案例
需求:在多线程场景下,在控制台输出:多线程程序启动啦
思路1:创建自定义多线程类实现Runnble接口,创建对象启动
思路2:优化使用匿名内部类的方式来完成
思路3:使用lambda表达式来完成
public class LambdaDemo {
public static void main(String[] args){
MyRunnable target = new MyRunnable();
Thread t = new Thread(target);
//启动线程
t.start();
//方案二:使用内部类的方式来实现
new Thread(new Runnable()){
@Override
public void run(){
System.out.println("多线程程序2启动啦");
}
}
//方案三:使用lambda表达式的方式来实现
new thread(() -> {
System.out.println("多线程程序3启动啦");
}).start();
}
}
//方案一:以接口实现类的方式来实现
//1.定义多线程类实现Runnable接口,重写run()
class MyRunnable implements Runnable{
@Override
public void run(){
System.out.println("多线程程序启动啦");
}
}
3、Lambda表达式的标准格式
先来分析一下以匿名内部类方式编写代码的格式:
1、方法的参数列表没有参数,说明该方法执行时不需要传参
2、方法的返回值类型是void,说明该方法执行时没有返回结果
3、方法中的内容才是我们具体要做的业务
然后再来分析以lambda表达式方式编写代码的格式:
1、()里面没有内容,我们可以把它看作是方法执行时不需要传参数,参数为空
2、->:用箭头表示我们即将要做的事,也就是具体要做的业务
3、{}:我们可以把它看作是一个代码块代表了之前我们在方法体中需要写的业务内容
总结: Lambda表达式的标准格式为:(方法的形式参数) -> {方法体}
1)如果有多个参数,参数之间用逗号隔开,如果没有参数,小括号里面为空
2)-> 是一个固定的标准写法,使用的符号为英文格式,代表我们指向要操作的动作
3){}里是我们具体要完成的业务,也就是我们方法的方法体
注意Lambda表达式的前提:接口+接口中有且仅有一个抽象方法
4、案例练习1:抽象方法无参数无返回值时:
创建接口:AirPlane
public interface AirPlane {
void fly();
}
创建接口的实现类:Air9cImpl
public class Air9cImpl implements AirPlane {
@Override
public void fly(){
System.out.println("春秋航司起飞啦");
}
}
创建测试类:TestAnimal
public class TestAirPlane {
public static void main(String[] args){
//方案一:
//创建接口的实现类
AirPlane airPlane = new Air9cImpl();
getAirPlane(airPlane);
//方案二:使用匿名内部类
getAirPlane(new AirPlane()){
@Override
public void fly(){
System.out.println("正在飞行中");
}
});
//方案三:使用lambda表达式
//fly()没有参数,小括号为空,指向eat()里实际要执行的一句打印语句
getAirPlane(() -> {
System.out.println("Lambda表达式的方式,飞的好");
});
}
//创建测试类的方法getAirPlane()
public static void getAirPlane(AirPlane airPlane){
airPlane.fly();
}
}
4、案例练习2:抽象方法有参数无返回值时:
创建接口:Fruit
//创建接口
public interface Fruit{
//创建接口中带参数的抽象方法
void getKind(String s);
}
创建接口测试类FruitImpl:
//创建接口的实现类并实现抽象方法
public class FruitImpl implements Fruit{
@Override
public void getKind(String s){
System.out.println("参数s是:"+s);
System.out.println("一只桃子~");
}
}
创建测试类TestFruit:
//创建测试类进行测试
public class TestFruit{
public static void main(String[] args){
//创建接口实现类对象调用
//创建接口的实现类对象【多态对象】
Fruit f = new FruitImpl();
//调用本类的getFuit(),并把刚刚创建的多态对象传入
getFruit(f);
//方案2:使用匿名内部类的方式来调用
//直接调用getFruit(),参数处以创建匿名内部类的方式来完成
getFruit(new Fruit(){
@Override
public void getKind(String s){
System.out.println("参数s是:"+s);
System.out.println("一只橙子~");
}
});
//方案3:使用lambda表达式来完成
//getKind()没有参数,小括号为空,指向getKind()里实际要执行的一句打印语句
getFruit((String s) -> {
System.out.println("参数s是:"+s);
System.out.println("一只草莓~");
});
}
//创建测试类的方法,需要传入接口对象,并且调用接口的功能
public static void getFruit(Fruit f){
f.getKind("什么口味的?");
}
}
4、案例练习3:抽象方法有参数有返回值时:
创建接口:Student
//创建接口
public interface Student {
//创建接口中带参数并且有返回值的抽象方法
int scoreCount(int a,int b, int c);
}
创建接口的实现类:
//创建接口的实现类并实现抽象方法
public class StudentImpl implements Student {
@Override
public int scoreCount(int a, int b, int c) {
return a+b+c;
}
}
创建测试类TestStudent:
//创建测试类进行测试
public class TestStudent {
public static void main(String[] args) {
//方案1:创建接口实现类对象调用
//创建接口的实现类对象【多态对象】
Student s = new StudentImpl();
//调用本类的getScore(),并把刚刚创建的多态对象传入
getScore(s);
//方案2:lambda表达式
getScore((int x, int y, int z) -> {
return x+y+z;//scoreCount()正常返回方法的返回值,交给下方的score变量来保存
});
}
//创建测试类的方法,需要传入接口对象,并且调用接口的功能
public static void getScore(Student s){
int score = s.score(60, 70, 80);
System.out.println("总分为:"+score);
}
}
5、Lambda表达式的省略模式
1、省略参数类型的简写形式1:
//Lambda表达式的省略模式1:
//参数的类型可以省略,但注意,如果有多个参数,不能只省略一个
//getScore((int x, int y, int z) -> {//之前的写法
//getScore((x, int y, int z) -> {//报错
getScore((x, y, z) -> {//现在省略了所有参数的类型
return x+y+z;//scoreCount()正常返回方法的返回值,交给下方的score变量来保存
});
结论:参数类型可以省略,但注意,如果有多个参数,不能只省略一个
2、省略的参数的类型与小括号的简写形式2:
//Lambda表达式的省略模式2:
//如果方法的参数有且只有一个,参数的小括号可以省略
//getFruit((String s) -> {//之前的写法,现在省略的参数的类型与小括号
getFruit( s -> {
System.out.println("参数s是:"+s);
System.out.println("一只草莓~");
});
结论:如果方法的参数有且只有一个,参数的小括号可以省略
3、省略大括号和分号的简写形式3:
//如果大括号里的方法体只有一句,可以省略大括号和分号
getAnimal(() ->
System.out.println("Lambda表达式的方式~");
);
结论:如果大括号里的方法体只有一句,可以省略大括号分号
4、大括号与分号,return也需要一起省略的简写形式4:
//如果方法体只有一句,大括号与分号可以省略
//除此之外,如果方法用关键字return返回值,return也需要一起省略
getScore((x, y, z) -> x+y+z );
结论:如果方法体里有return用来返回返回值,return也需要一起省略掉
6、Lambda表达式的注意事项:
1、必须是有一个接口,并且接口中只有一个抽象方法时使用
2、使用表达式时必须要有上下文环境推导出Lambda实际代表的接口
3、匿名内部类与Lambda表达式的区别/使用场景:
1)不论被调用方法的参数是接口/抽象类/实体类,匿名内部类的形式均可以使用,但是Lambda表达式只能是被调用方法参数为接口的时候使用
2)不论接口里有几个抽象方法,都可以使用匿名内部类的形式,但是Lambda表达式只支持接口中有且仅有一个抽象方法的情况
3)实现原理不同:匿名内部类生效后会产生一个额外单独的内部类字节码文件,而Lambda表达式只有一个字节码文件
文章介绍了Lambda表达式在Java中的应用,包括简化多线程程序的创建、函数式编程思想以及Lambda的格式和使用。通过对比传统匿名内部类和Lambda,展示了Lambda如何使代码更加简洁。文章提供了多个案例,包括无参数无返回值、有参数无返回值和有参数有返回值的Lambda表达式,并讨论了Lambda的省略模式和注意事项。
1466

被折叠的 条评论
为什么被折叠?



