Lambda 表达式

Lambda 表达式

创建线程对比

一般写法:

public class LambdaTest implements Runnable {
    public static void main(String[] args) {
        new Thread(new LambdaTest()).start();
    }
    @Override
    public void run() {
        System.out.print("start");
    }
}

lambda表达式写法

public class LambdaTest {
    public static void main(String[] args) {
        new Thread(()->{
            System.out.print("start");
        }).start();
    }

}

说明:

lambda中

  • ()里没有内容,可以看作形参,如果有参数,可以用逗号隔开。
  • -> 指要做的事情
  • {} 指代码块,可以理解为我们要做的内容。

Lambda表达式练习

使用前提:

  • 有一个接口
  • 接口只有一个抽象方法

无参写法

同理,我们可以高仿线程的创建进行练习;

首先创建一个接口

public interface ILambdaTest {

    void start();
}

我们想要通过这个接口做一些事情的话,一般的写法如下:

创建一个实现类

public class ILambdaImpl implements ILambdaTest {
    @Override
    public void start() {
        System.out.print("start");
    }
}

main 进行调用

public class LambdaTest {
    public static void main(String[] args) {
            ILambdaTest test = new ILambdaImpl();
            test.start();
    }

}

如此写法相对复杂

Lambda写法对比

public class LambdaTest {
    public static void main(String[] args) {
            new LambdaTest().start(()->{
                System.out.print("start");
            });
    }
    private void start(ILambdaTest test){
        test.start();
    }
}

有参写法

如果接口有参数的话,在() 中用逗号隔开就好,另外传入的参数类型是可以省略的。

public interface ILambdaTest {

    String start(String s,String y);
}

例如:

// 写法1
public class LambdaTest {
    public static void main(String[] args) {
            LambdaTest t = new LambdaTest();
            String s= t.start((String x,String y)->{
                System.out.println(x+y);
                return "lambda start";
            });
            System.out.println(s);
    }
    private String start(ILambdaTest test){
        return test.start("sss","yyyy");
    }
}
// 写法2 省略类型
public class LambdaTest {
    public static void main(String[] args) {
            LambdaTest t = new LambdaTest();
            String s= t.start(( x, y)->{
                System.out.println(x+y);
                return "lambda start";
            });
            System.out.println(s);
    }
    private String start(ILambdaTest test){
        return test.start("sss","yyyy");
    }
}

有参省略写法

这是在两个参数的时候,如果只有一个参数的时候,括号都可以省略

例如:

public interface ILambdaTest {

    String start(String s);
}

省略写法

public class LambdaTest {
    public static void main(String[] args) {
            LambdaTest t = new LambdaTest();
            String s= t.start(x->{
                System.out.println(x);
                return "lambda start";
            });
            System.out.println(s);
    }
    private String start(ILambdaTest test){
        return test.start("sss");
    }
}

如果代码块也只有一条的情况下,大括号,分号也可以省略

例如:

public interface ILambdaTest {

    void start(String s);
}

public class LambdaTest {
    public static void main(String[] args) {
            LambdaTest t = new LambdaTest();
            t.start(x->System.out.print("yyy"));
    }
    private void start(ILambdaTest test){
          test.start("sss");
    }
}

如果有值需要return时需要注意

如果有return 时 并且只有一行代码块去掉分号、大括号的同时 ,return也要去掉

例如:

public interface ILambdaTest {

    String start(String s);
}


如下写法;

public class LambdaTest {
    public static void main(String[] args) {
            LambdaTest t = new LambdaTest();
            t.start(x->x);
    }
    private void start(ILambdaTest test){
          test.start("sss");
    }
}

lambda表达式和匿名内部类的区别

使用限制不同

  • 匿名内部类可以是接口,可以是抽象类,也可以是具体类
  • Lambda表达式只能是接口,而且接口只能有一个方法
  • 如果在接口中有多个方法的话,只能使用匿名内部类的方式

例如:有抽象类,接口,和普通类

public abstract class AbstractLambdaTest {
    abstract String start(String str);
}

public interface ILambdaTest {
    String start(String s);
}
public class ILambdaImpl implements ILambdaTest {
    @Override
    public String start(String s) {
        System.out.print(s);
        return "";
    }
}

有如上内容,我们同时用匿名内部类的方式调用

public class LambdaTest {
    public static void main(String[] args) {
            interfaceTest(new ILambdaTest() {
                @Override
                public String start(String s) {
                    return "start";
                }
            });
            CLassTest(new ILambdaImpl(){
                @Override
                public String start(String s) {
                    return "start";
                }
            });
            AbstractLambdaTest(new AbstractLambdaTest() {
                @Override
                String start(String str) {
                    return "str";
                }
            });
    }
    private static void interfaceTest(ILambdaTest test){
        test.start("sss");
    }
    private static void CLassTest(ILambdaImpl test){
        test.start("sss");
    }
    private static void AbstractLambdaTest(AbstractLambdaTest test){
        test.start("sss");
    }
}

如上,用匿名内部类的方式是可以通过编译的;

但是用Lambda表达式的方式无法通过编译

public class LambdaTest {
    public static void main(String[] args) {
        // 这个可以通过编译,因为这是个接口
            interfaceTest((s)->{
                return "";
            });
        //无法通过编译
            CLassTest((s)->{
                return "";
            });
        //无法通过编译
            AbstractLambdaTest((s)->{
                return "";
            });
    }
    private static void interfaceTest(ILambdaTest test){
        test.start("sss");
    }
    private static void CLassTest(ILambdaImpl test){
        test.start("sss");
    }
    private static void AbstractLambdaTest(AbstractLambdaTest test){
        test.start("sss");
    }
}

此次实验再次说明在使用Lambda表达式的前提是,在接口中, 有且只有一个方法的时候。

字节码文件不同

​ 在使用匿名内部类的时候,会单独的生成一个.class字节码文件,Lambda表达式在运行的时候,会在运行的时候动态生成。

在这里插入图片描述

总结

有参总结:

  • 参数类型可以省略不写,但是多个参数时,要么不省略,要么同时省略;
  • 如果参数只有一个,小括号可以省略
  • 如果代码块只有一条,大括号和分号可以省略,如果有return 也要省略。

再次强调:

  • 使用Lambda 必须要有接口,接口中只能有一个抽象方法
  • Lambda 使用时必须要有上下文环境,才能到处Lambda对应的接口; #1

1.上面第二句话可能不好理解。在此解释

例如:

public class LambdaTest {
    public static void main(String[] args) {
        new Thread(()->{
            System.out.print("start");
        }).start();
    }


    //如上写法 中的 ()->{Sysout.out.print("start")} 
    //其实是代替了new Runable(){public void run(){}}
    // 如果没有在new Thread()中,那这个语句就什么都不是。就无法推导 出是什么

    public static void main(String[] args) {
        ()->{System.out.print("start");}
    }

    // 正确的写法如下
    public static void main(String[] args) {
        Runnable runnable = ()->System.out.print("start");
        new Thread(runnable).start();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叁滴水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值