函数式接口实例化的替代方案

什么是Lambda表达式?

Lambda表达式是Java8的新特性,Java8允许程序通过该表达式来代替功能接口。从而达到简化冗余代码,提高开发效率的效果,也可以说是函数式接口实例化的替代方案。
编译器在编译使用Lambda表达式的类时,会在该类中创建一个匿名内部类。并在内部类中定义一个静态方法。

为什么要使用Lambda表达式?

举个简单的例子。假设我们现在需要启动一个线程去完成一个无需返回值的任务。
通常我们会创建一个Runnable接口的匿名内部类对象来指定任务内容,再将其交给一个线程来启动。
Idea代码为:

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("需要执行的代码");
            }
        });
        thread.start();
    }
}

控制台的输出为:
在这里插入图片描述

我们不妨分析一下,我们最初的想法只是启动一个线程去完成一个无返回值任务。
但想要完成这个任务Thread类又需要我们传递一个Runnable对象。
而Runnable又是一个接口,为了避免定义实现类,我们又使用了匿名内部类的方式创建该对象。
为了创建该对象我们又必须重写其抽象方法,且方法名称、方法参数、方法返回值类型不得不重写一遍,且不能写错。
实际上,只有run方法方法体中的代码才是我们想执行的操作。
其他代码都是为了让run方法方法体中的代码能成功被Thread类获取,而编写的。
我们真的希望创建一个Runnable对象吗?不。我们只是为了完成这件事情而不得不创建一个对象。
我们希望的只是将run方法的方法体传递给Thread类,让其知晓它应该做什么。
创建Runnable对象只是受限于面向对象语法而不得不采取的一种手段方式。
那,有没有更加简单的办法?
而这个问题的解决方案,就是Lambda表达式

如何使用Lambda表达式

1.标准语法:

	([parameter, ...])->{
	}
	([parameter, ...])代表的是接口中抽象方法的形参列表,
	{}代表的则是该抽象方法的方法体。

将之前的例子使用Lambda表达式书写
Idea代码为:

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            System.out.println("需要执行的代码");
        });
        thread.start();
    }
}

控制台输出为:
在这里插入图片描述

Thread构造参数中的“()”就代表run方法的形参列表,而->所指向的就是run方法的方法体。
这段代码和刚才的执行效果是完全一样的,可以在1.8或更高的编译级别下通过。
从代码的语义中可以看出:我们创建了一个线程,而线程任务的内容以一种更加简洁的形式被指定。
2.省略写法

	1.当方法形参个数为一个时,"()"可省略。
	2.当方法体执行语句只有一句时"{} return ;"都可省略

将之前的例子使用Lambda表达式的省略写法书写
Idea代码:


public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(()->System.out.print("需要执行的代码"));
        thread.start();
    }
}

控制台输出:
在这里插入图片描述
值得注意的是无论是标准写法还是省略写法,Lambda表达式只对函数式接口或SAM接口有效

延迟加载

在程序运行时,都会用到日志,而日志打印或多或少都会出现某些资源浪费的情况,例如打印错误信息时,需要根据错误的级别可打印的日志也不相同。

未使用Lambda的代码

public static void main(String[] args) {
    int code = 0;
    String message1 = "出现了";
    String message2 = "exception";
    logPrint(code, message1+message2);
}

/**
 * 打印日志
 * @param code 错误级别 0代表无错误 1代表出现错误
 * @param message 打印信息
 */
public static void logPrint(int code, String message){
    if(code != 0){
        System.out.println(message);
    }
}

从上面代码可以发现,code的值无论为何值,程序都会有一次字符串拼接的操作
下面我们来看使用Lambda表达式后的代码。

/**
 * 自定义的打印接口
 */
@FunctionalInterface
interface MessagePrint{
    /**
     * 打印日志
     * @param code 错误级别 0代表无错误 1代表出现错误
     */
    void logPrint(int code);
}



public static void main(String[] args) {
    int code = 1;
    String message1 = "出现了";
    String message2 = "exception";
    logPrint(code, (x)-> {
        if(x==1){
            System.out.println(message1+message2);
        }
    });
}

public static void logPrint(int code, MessagePrint mt){
    mt.logPrint(code);
}

以上代码当且仅当code为1时,才会进行字符串拼接的操作,这就是Lambda的又一特性——延迟加载(懒加载)

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

早川不爱吃香菜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值