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

相关推荐
麦兜*39 分钟前
Spring Boot 企业级动态权限全栈深度解决方案,设计思路,代码分析
java·spring boot·后端·spring·spring cloud·性能优化·springcloud
序属秋秋秋40 分钟前
《C++初阶之内存管理》【内存分布 + operator new/delete + 定位new】
开发语言·c++·笔记·学习
ruan1145142 小时前
MySQL4种隔离级别
java·开发语言·mysql
quant_19863 小时前
R语言如何接入实时行情接口
开发语言·经验分享·笔记·python·websocket·金融·r语言
Hellyc6 小时前
基于模板设计模式开发优惠券推送功能以及对过期优惠卷进行定时清理
java·数据库·设计模式·rocketmq
lifallen6 小时前
Paimon LSM Tree Compaction 策略
java·大数据·数据结构·数据库·算法·lsm-tree
hdsoft_huge6 小时前
SpringBoot 与 JPA 整合全解析:架构优势、应用场景、集成指南与最佳实践
java·spring boot·架构
百锦再7 小时前
详细解析 .NET 依赖注入的三种生命周期模式
java·开发语言·.net·di·注入·模式·依赖
程序员的世界你不懂7 小时前
基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(2)对框架加入业务逻辑层
java·selenium·maven
风吹落叶花飘荡7 小时前
2025 Next.js项目提前编译并在服务器
服务器·开发语言·javascript