2021-09-24 Lambda表达式

1. Lambda表达式的标准格式

Lambda表达式的标准格式为:(方法的形式参数)-> { 方法体 }

1)如果有多个参数,参数之间用逗号隔开,如果没有参数,小括号里面为空
2)-> 是一个固定的标准写法,使用的符号都是英文的,代表我们指向要操作的动作
3){ } 里是我们具体要完成的业务,也就是我们方法的方法体
注意Lambda表达式的前提:接口+接口中有且仅有一个抽象方法

2. 抽象方法有参数有返回值时

创建接口:Student

package cn.cxy.lambda;
//1.创建接口
public interface Student {
    //2.创建接口中带参数并且有返回值的抽象方法
    int scoreCount(int a,int b,int c);
}

创建接口的实现类:

package cn.cxy.lambda;
//3.创建接口的实现类并实现抽象方法
public class StudentImpl implements Student{
    @Override
    public int scoreCount(int a, int b, int c) {
        return a+b+c;
    }
}

创建测试类TestStudent:

package cn.cxy.lambda;

//4.创建测试类进行测试
public class TestStudent {
    public static void main(String[] args) {
        /*方案1:创建接口实现类对象调用*/
        //1.创建接口的实现类对象【多态对象】
        Student s = new StudentImpl();
        //2.调用本类的getFruit(),并把刚刚创建的多态对象传入
        getScore(s);
        //方案2:使用匿名内部类的方式来调用
        /*匿名内部类其实就充当了实现类的角色,去实现未实现的抽象方法,只是没有名字而已
         *匿名内部类属于局部内部类,而且是没有名字的局部内部类,通常和匿名对象一起使用*/
        getScore(new Student() {
            @Override
            public int scoreCount(int a, int b, int c) {
                return a + b + c;
            }
        });
        /*匿名内部类的方式来调用也不简单,故此直接使用Lambda表达式来完成:
        * 调用本方法时,将下方的参数60 70 80 作为参数传入*/
        //方案3:直接使用Lambda表达式进行优化
        getScore((int a,int b,int c) ->{
            return a+b+c;//scoreCount()正常返回方法的返回值,交给下方的score变量来保存
        });
    }

    //5.创建测试类的方法,需要传入接口对象,并且调用接口的功能
    public static void getScore(Student s) {
        int score = s.scoreCount(60, 70, 80);
        System.out.println("总分为:"+score);
    }
}

3. Lambda表达式的省略模式

1.在TestStudent测试类中,我们来学习Lambda表达式的简写形式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.Lambda表达式的简写形式2:

	/*Lambda表达式的省略模式2:
     * 如果方法的参数有且只有一个,参数的小括号可以省略*/
    //getFruit( (String s) -> {//之前的写法,现在省略的参数的类型与小括号
      getFruit( s -> {
         System.out.println("参数s是:"+s);
         System.out.println("我是一颗大草莓");
      });

结论:如果方法的参数有且只有一个,参数的小括号可以省略

3.Lambda表达式的简写形式3:

/*Lambda表达式的省略模式3:
     * 如果大括号里的方法体只有一句,可以省略大括号和分号*/
     getAnimal( () -> 
        System.out.println("Lambda表达式的方式,小动物们都惊呆了~")
     );

结论;如果大括号里的方法体只有一句,可以省略大括号和分号

4.Lambda表达式的简写形式4:

	/*Lambda表达式的省略模式4:
     * 如果方法体只有一句,大括号与分号可以省略
     * 除此之外,如果方法用关键字return返回返回值,return也需要一起省略掉*/
     getScore((x,y,z) -> x+y+z );

结论:如果方法体里有return用来返回返回值,return也需要一起省略掉

4. Lambda表达式的注意事项:

1.必须是有一个接口,并且接口中只有一个抽象方法时使用
2.使用表达式时必须要有上下文环境推导出Lambda实际代表的接口

package cn.cxy.lambda;

public class TestLambda {
    public static void main(String[] args) {
        /*方式1:匿名内部类*/
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程启动啦");
            }
        }).start();
        /*方式2:Lambda表达式写法1:根据局部变量r的类型推导出Lambda代表的接口*/
        Runnable r = () -> System.out.println("用引用类型变量推断Lambda表示的是哪个接口");
        new Thread(r).start();

        /*方式3:Lambda表达式写法2:根据调用Thread(Runnable)方法的参数类型推导出Lambda代表的接口*/
        new Thread(()-> System.out.println("Lambda方式线程启动啦")).start();
    }
}

3.匿名内部类与Lambda表达式的区别/使用场景:
1)不论被调用方法的参数是接口/抽象类/实体类,匿名内部类的形式均可以使用
但是Lambda表达式只能是被调用方法参数为接口的时候使用
2)不论接口里有几个抽象方法,都可以使用匿名内部类的形式
但是Lambda表达式只支持接口中有且仅有一个抽象方法的情况
3)实现原理不同:匿名内部类生效后会多产生一个额外单独的内部类字节码文件
而Lambda表达式只有一个字节码文件
在这里插入图片描述
创建接口:

package cn.cxy.lambda;
//1.创建接口与接口中的抽象方法
public interface Inter {
    void eat();
}

创建抽象类:

package cn.cxy.lambda;
//2.创建抽象类与抽象类中的方法
public abstract class abstractClass {
    abstract void sleep();
    public void sleep2(){
        System.out.println("一天要睡够8小时哦~");
    }
}

创建普通类:

```java
package cn.cxy.lambda;
//3.创建普通实体类与类中的方法
public class normalClass {
    public void play(){
        System.out.println("最爱玩的就是代码啦~");
    }
}

创建测试类:

package cn.cxy.lambda;

public class TestAnonymousAndLambda {
    public static void main(String[] args) {
        useFunction1(new Inter() {
            @Override
            public void eat() {
                System.out.println("吃火锅~");
            }
        });
        useFunction2(new abstractClass() {
            @Override
            void sleep() {
                System.out.println("睡10个小时吧~");
            }
        });
        useFunction3(new normalClass() {
            @Override
            public void play() {
                System.out.println("代码写累了,完会游戏吧~");
            }
        });
        useFunction1(()-> System.out.println("我是接口形式"));
        //useFunction2(()-> System.out.println("我是抽象类的形式"));//会报错,不支持抽象类
        //useFunction3(()-> System.out.println("我是普通实体类的形式"));//会报错,不支持普通类
    }

    public static void useFunction1(Inter i) {
        i.eat();
    }

    public static void useFunction2(abstractClass a) {
        a.sleep();
    }

    public static void useFunction3(normalClass n) {
        n.play();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值