java函数式接口和Lambda表达式

函数式接口

一种编程范式,主要关注处理数据的函数

函数式接口是指有且仅有一个抽象方法的接口,可以使用@Functionallnterface注解进行标识,函数式接口可以用Lambda表达式来实现,从而简化代码的编写

java 复制代码
@Functionallnterface
interface 接口名{
	唯一的抽象方法
}
函数式接口的注意事项

1,函数式接口的准确定义为有且有且仅有一个抽象方法需要重写

在接口中添加Object类中的方法作为抽象方法,子类可以不重写

Lambda表达式介绍

jdk8引入

只能操作函数式接口
当需要一个函数式接口的实现类对象时使用

1,概述

Lambda表达式由三个部分组成,参数列表,箭头符号和方法体

(parameters)-> {方法体}

Lambda的完全形式

java 复制代码
(T 参数1,T 参数2) -> {语句1;
			 语句2;}

参数列表:包含在括号中,可以省略参数类型

即函数式接口中唯一抽象方法的参数

箭头符号:由"->"组成,将参数和方法体分开

方法体:可以是表达式或者语句块

即函数式接口唯一抽象方法的重写形式
Lambda表达式的应用场景:

1,使用Lambda表达式可以简化匿名内部类的使用

2,可以作为方法参数传递,用于简化回调函数的编写

3,可以用于集合的遍历和筛选操作,简化代码-->Stream流体现

Lambda表达式代码实现:

1,无参无返回值情况
java 复制代码
 @FunctionalInterface
2 interface NoParamNoReturn {
3 	void execute();
4 }
	
// ⽆参⽆返回值的情况
27 public static void executeNoParamNoReturn(NoParamNoReturn func) {
28 func.execute();
29 }

在executeNoParamNoReturn()方法中传入一个NoParamNoReturn接口类型的参数,需要传入一个接口类型的实现类对象,

在之前,我们通常使用匿名内部类进行传入,但是当这个接口中有且仅有一个需要重写的抽象方法时,即这个接口为函数式接口时

我们可以使用Lambda表达式进行简化

java 复制代码
public static void main(String[] args) {
        executeNoParamNoReturn(()->{
            System.out.println("已传递");
        });
    }

调用方法,传入lambda表达式,因为没有参数列表,所以在小括号中无需传入参数,在方法体中因为没有返回值,所以不需要return语句.

传递完接口实现类对象,方法内执行接口实现类对象重写的execute()方法,即输出"已传递".

再来看看其他情况

2,有参有返回值情况
java 复制代码
@FunctionalInterface
interface WithParamWithReturn {
    int add(int a, int b);
}

//有参有返回值的情况
public static int executeWithParamWithReturn(WithParamWithReturn func, int a, int b) {
        return func.add(a, b);
}

public static void main(String[] args) {
        System.out.println(executeWithParamWithReturn((int c,int d)->{
            System.out.println(1);
            return c+d;},1,2));
 }

在测试方法中我们调用executeWithParamWithReturn()方法,可以看到需要传入三个参数:

一个WithParamWithReturn接口类型的实现类对象,

一个int类型的 a

一个int类型的 b

在main方法中我们在需要实现类对象的位置传入lambda表达式

java 复制代码
(int c,int d)->{
    		System.out.println(1);
            return c+d;
}

因为接口内的抽象方法要求传入两个int类型的参数,所以我们相对的也需要传入两个int类型的参数

即小括号内的c 和 d

又因为抽象方法要求一个int类型的返回值,所以我们相对的也需要在返回语句中return一个int类型的值

即return c+d

在方法体中我们又自由发挥了一行语句,输出了一个1


分析到此结束,我们来看一下执行流程

首先在main方法中调用executeWithParamWithReturn()方法,传入WithParamWithReturn类型参数,

即lambda表达式

再传入int类型参数1和2

执行executeWithParamWithReturn()中的方法体

java 复制代码
return func.add(a, b);

返回了接口实现类对象重写的方法的返回值

而我们重写的方法的方法体如下所示

java 复制代码
System.out.println(1);
            return c+d;

在输出1的同时,返回了c+d,也就是参数列表中的a+b,也就是3

再返回给方法调用者executeWithParamWithReturn(),再返回给其调用者主方法

java 复制代码
public static void main(String[] args) {
        System.out.println(executeWithParamWithReturn((int c,int d)->{
            System.out.println(1);
            return c+d;},1,2));
 }

在主方法中我们将返回值打印

所以最后控制台的结果如下

3,lambda表达式的简化

lambda表达式的简化

参数列表中的类型可以省略

参数列表中如果只有一个参数可以省略小括号

方法体中如果只有一句语句可以省略大括号和分号

如果这行代码是return语句,return必须省略

先写一个完整的lambda表达式

java 复制代码
@FunctionalInterface
interface Test {
    int test(int a);
}

public static void main(String[] args) {
     Test test = (int a)->{return a+1;};
     System.out.println(test.test(1));
}

在省略参数类型,参数括号和方法体括号和分号以及return后我们得到

java 复制代码
public static void main(String[] args) {
     Test test = a->a+1;
     System.out.println(test.test(1));
}

有一种热兵器暴打原始人的感觉...

总结:

lambda表达式是一种语法糖,极大的简化了对接口进行创建实现类对象的操作,在接口为函数式接口的前提下完全替代了匿名内部类,使代码显得更加简洁精练.

相关推荐
shinelord明几秒前
【再谈设计模式】享元模式~对象共享的优化妙手
开发语言·数据结构·算法·设计模式·软件工程
新手小袁_J6 分钟前
JDK11下载安装和配置超详细过程
java·spring cloud·jdk·maven·mybatis·jdk11
呆呆小雅7 分钟前
C#关键字volatile
java·redis·c#
Monly217 分钟前
Java(若依):修改Tomcat的版本
java·开发语言·tomcat
boligongzhu8 分钟前
DALSA工业相机SDK二次开发(图像采集及保存)C#版
开发语言·c#·dalsa
Eric.Lee20218 分钟前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频
Ttang239 分钟前
Tomcat原理(6)——tomcat完整实现
java·tomcat
7yewh11 分钟前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
钱多多_qdd20 分钟前
spring cache源码解析(四)——从@EnableCaching开始来阅读源码
java·spring boot·spring
waicsdn_haha22 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk