JAVA 函数式接口与lambda

news2024/11/26 3:53:35

1.函数式定义

什么是函数式接口呢?听起来很绕,我们可以这样理解:

可以接收lambda函数接口,就可以叫做函数式接口。

注意一个函数式接口里,只允许定义一个抽象方法。

在java里可以用@FunctionalInterface注解来标注函数式接口, 比如Runnable就是一个函数式接口:

@FunctionalInterface
public interface Runnable {
    void run();
}

2. 函数式接口有什么用?

现在我们知道了,函数式接口可以接收lambda表达式,首先我们分析下函数式接口有什么用。

2.1 函数式接口,可以接收一个方法!

Q: 那一个函数式接口,接收一个方法,又有何用?

答:可以让我们的代码更加灵活,其实方法作为参数,在很多脚本语言里是非常常见的,比如js、python。

我们思考一个问题:如何加强一个方法?

作为一名java开发,是不是一大堆名词涌入脑海?

比如AOP?代理模式?装饰者模式?

上述方法固然可以实现,但却很略显繁琐。

2.2 加强一个方法

假如我们要对下述方法做增强,

    public static void originMethod() {
        System.out.println("原方法");
    }

目标:在originMethod前后分别打印一些东西,

最简单的方法是不是这样:

    public static void decorate() {
        System.out.println("===方法前加强");
        originMethod();
        System.out.println("===方法后加强");
    }

但如果我们还需要加强其他的方法呢?再写一个decorate吗?

显然这种方法并不好,

那我们看看,使用函数式接口,怎么解决这个问题。

下面的代码是一个初版,先让大家回忆一下,Runnable是怎么用的。

    public static void originMethod() {
        System.out.println("原方法");
    }

    public static void main(String[] args) {

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("===方法前加强");
                originMethod();
                System.out.println("===方法后加强");
            }
        };
        runnable.run();
    }

但是上述代码不能通用,所以我们把加强方法抽取出来,变成方法decorateOriginMethod,代码如下:

可以看到,我们把originMethod()方法,传递给了形参method

你可能会说,哎不对,我传给形参method的是Runnable对象,你这么说也对,但我觉得不重要,因为上文提到:函数式接口里只有一个抽象方法。

所以形参method,接收的到底是函数式接口,还是方法,区别也不大。

2.3 lambda表达式简写函数式接口

刚才创建Runnble的代码很繁琐,使用lambda表达式简写如下:

    public static void main(String[] args) {
//        decorateOriginMethod(new Runnable() {
//            @Override
//            public void run() {
//                originMethod();
//            }
//        });
        // lambda表达式简写
        decorateOriginMethod(() -> originMethod());
    }

其实函数式接口就这么简单,至于那些什么Predicate,Supplier,Consumer这些花里胡哨的,与Runnable都是一样的原理,都是函数式接口而已,不要被吓到了。

区别在哪呢?其实就是:

函数式接口里,方法的入参和返回值类型不一样罢了

我们知道,Runnable入参和返回值都是void,

而java帮我们准备了一些默认的函数式接口,分别适用于不同的入参和返回值(如下图所示)。

当然你完全可以自己定义类似的函数式接口。

3.函数式接口,在框架里的使用

在阅读源码时,可以说函数式接口是绕不过去的。

尤其是Spring里特别多,而Mybatis里,倒是没怎么见到。

3.1 Spring事务里函数式接口的应用

我们看看如下方法的源码(删去了多于代码):org.springframework.transaction.support.TransactionTemplate#execute

    @Override
	@Nullable
	public <T> T execute(TransactionCallback<T> action) throws TransactionException {
            获取事务
			TransactionStatus status = this.transactionManager.getTransaction(this);
			T result;
			 
            //TransactionCallback是函数式接口,里面有唯一一个方法doInTransaction
            //执行真实的业务
			result = action.doInTransaction(status);
		
		    // 提交事务
			this.transactionManager.commit(status);
			return result;
		
	}

如上代码所示,我们把业务逻辑传给函数式接口TransactionCallback,然后框架帮我们增强了事务获取、提交、回滚等操作。

后记:

很久没发文章了,原力值没了,所以先写一篇。

其实函数式接口没什么神秘的,我个人感觉它就是一个新类型:方法。最典型的就是接收一个lambda表达式。

当然java类型里没有方法这一说,只是个人理解。

如果各位懂了,可以进一步趁热打铁,思考一下闭包是什么

其实java用函数式接口就可以实现闭包了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/977164.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

优维低代码实践:函数

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

【STM32RT-Thread零基础入门】8. 基于 CubeMX 移植 RT-Thread Nano

硬件&#xff1a;STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 文章目录 前言一、cubemx配置二、board.c文件修改2.rtconfig.h文件修改 三、主程序1. main函数2. task函数 总结 前言 利用RT_Thread操作系统实现三种不同的…

Ubuntu下安装Clion

前言 CLion 是一款由 JetBrains 开发的 C 集成开发环境&#xff08;IDE&#xff09;&#xff0c;它拥有许多强大的功能&#xff0c;如代码自动完成、调试器、版本控制等等。CLion本身是收费软件&#xff0c;但如果是学生的话可以申请免费使用。 测试安装环境&#xff1a;Ubunt…

Vue + Element UI 前端篇(十):动态加载菜单

Vue Element UI 实现权限管理系统 前端篇&#xff08;十&#xff09;&#xff1a;动态加载菜单 动态加载菜单 之前我们的导航树都是写死在页面里的&#xff0c;而实际应用中是需要从后台服务器获取菜单数据之后动态生成的。 我们在这里就用上一篇准备好的数据格式Mock出模…

哈希的应用——位图

文章目录 前言1. 面试题思考2. 位图2.1 位图的概念2.2 思路讲解及代码实现结构定义构造函数set和reset接口实现set和reset测试观察test接口实现test接口测试思考 3. 位图的应用习题1习题2习题3 4. 总结5. 源码5.1 bitset.h5.2 Test.c 前言 前面的文章里我们学习了哈希表&#x…

Etherpad安装手册(win10 64位电脑)

Etherpad安装手册 我使用的为win10 64位电脑 一、按照教程下载安装Etherpad 按照该文章下载安装&#xff0c;下面记录我的过程 1.下载etherpad 2.解压缩etherpad到d盘 3.双击start.bat&#xff0c;启动编辑器服务 注意&#xff1a;可能出现问题如下图&#xff0c;跳转二 4.在…

数据库管理-第100期 Refreshable Clone PDBs(20230905)

数据库管理-第100期 Refreshable Clone PDBs&#xff08;20230905&#xff09; 上周五&#xff0c;9月1日&#xff0c;我于上海Oracle办公室OU考场完成了19c OCM Upgrade考试&#xff0c;感受就是&#xff0c;很多新特性考的比想象的更加深入&#xff0c;希望最终结果是好的吧…

AVL树的旋转与插入

题&#xff1a;点我 题目大意&#xff1a;旋转 A V L AVL AVL树 在 A V L AVL AVL操作中主要有两种主要操作&#xff0c;分别是 L L LL LL和 R R RR RR&#xff0c;其中 L L LL LL的旋转本质是希望发生以下的转变 而 R R RR RR的本质是希望发生以下的转变&#xff1a; 如我们…

【面试题】如何实现数组去重的?有几种方式?

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 【国庆头像】- 国庆爱国 程序员头像&#xff01;总有一款适合你&#xff01; 1. 方法一&#xff1a;利用两层循环数组的splice方法 通过两层循环对数组…

TTransportException SASL authentication not complete

今天遇见了一个异常&#xff0c;但是发现是自己智障了 但还是记录一下 在close的时候先close了conn再close的statement导致报的这个错

工业、交通、电力、水务】LEAP模型应用及碳排放预测

中文名&#xff1a;LEAP模型 外文名&#xff1a;Long Range Energy Alternatives Planning System/ Low emission analysis platform LEAP模型[1]允许研究者根据研究目的、数据可获取度、研究对象特点等灵活构建模型结构&#xff0c;十分适用于能源数据不全面情况&#xff0c…

网络安全-IP地址信息收集

本文为作者学习文章&#xff0c;按作者习惯写成&#xff0c;如有错误或需要追加内容请留言&#xff08;不喜勿喷&#xff09; 本文为追加文章&#xff0c;后期慢慢追加 IP反查域名 http://stool.chinaz.com/same https://tools.ipip.net/ipdomain.php 如果渗透目标为虚拟主机…

HCIP自我重修总笔记

第一章.复习OSITCP/IP 模型 &#xff08;2023 9/5&#xff09; OSI 模型: 开放式系统互联参考模型 应用层&#xff1a;抽象语言-->编码表示层&#xff1a;编码--->二进制会话层&#xff1a;提供会话地址&#xff0c;建立应用程序端到端的会话 上三层为应用程序对数据加…

SQL注入 - 宽字节注入

文章目录 SQL注入 - 宽字节注入宽字节注入前置知识宽字节靶场实战判断是否存在SQL注入判断位数判显错位判库名判表名判列名 SQL注入 - 宽字节注入 靶场 sqli - labs less-32 宽字节注入主要是绕过魔术引号的&#xff0c;数据库解析中除了UTF-8编码外的所有编码如&#xff1a;G…

ctfshow 反序列化

PHP反序列化前置知识 序列化和反序列化 对象是不能在字节流中传输的&#xff0c;序列化就是把对象转化为字符串以便存储和传输&#xff0c;反序列化就是将字符串转化为对象 魔术方法 __construct() //构造&#xff0c;当对象new时调用 __wakeup() //执行unserialize()时&am…

结构体做函数参数

①值传递 ②地址传递 #include <iostream> #include <algorithm> #include <string> using namespace std; struct stu {int age;string name; }; void printStu(stu a) {cout << a.age << << a.name << endl; } void printstu(…

英语之美:用一句话解释句子结构

以下是一个包含主语、谓语、宾语、表语、定语、同位语、补足语和状语的扩展句子&#xff0c;使用 “I love you” 作为基础&#xff1a; “I, the person who truly loves you, consider our love a beautiful gift, and I love you more deeply with each passing day.” 在…

复制tr的一行数据或者复制数据使用,使用jq和php

效果图&#xff1a; 2.Html <!--复制的tr数据&#xff0c;s----------------------------------------------------------------------------------------------->{foreach from$arrs keykk itemvv} <tr><td style"text-align:center;" >1</t…

华为OD机试 - 关联子串 - 滑动窗口(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明4、换个思路 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A…

【C++】STL-函数对象-内建函数对象

0.前言 1.算术仿函数 #include <iostream> using namespace std;// STL-内建函数对象-算术仿函数 #include<functional> // 内建函数对象头文件//以下举例两个仿函数 -- negate and plus// negate 一元仿函数 取反仿函数 void test01() {negate<int>n;cout …