【响应式编程-05】Lambda方法引用

一、简要描述

Lambda的方法引用也叫引用方法

  • 方法引用初体验
  • 方法引用的底层实现
  • 方法引用的语法格式
  • 方法引用举例
    • 静态方法引用
    • 构造方法引用
    • 普通方法引用
    • super和this方法引用
    • 数组的方法引用

二、方法引用初体验

为什么出现方法引用?

  • 引用已存在方法,避免重复逻辑
  • 代码更加简洁

Lambda函数体以存在,是否还有存在的必要? 答案是:没有存在的必要,直接方法引用调用。

三、方法引用的底层实现

1、使用cfr工具包解码Lambda字节码

使用java命令,cfr工具解析字节码 java -jar cfr-0.145.jar MethodReferenceFirstGo.class --decodelambdas false

2、使用Java命令打开dumps调试模式

Java命令java -Djdk.internal.lambda.dumpProxyClasses ClassName

打开调试模式

2.1、生成Lambda编译的class文件

生成后编译后的文件:

  • MethodReferenceFirstGo$$Lambda$1.class
  • MethodReferenceFirstGo$$Lambda$2.class

2.2、两个文件进行对比

四、方法引用语法格式

  • 方法引用运算符

        双冒号 ::

  • 那些方法可以引用?
    • 类方法 / 构造方法 / 实例方法
    • 被引用方法与函数式接口抽象方法:
      • 参数列表相同
      • 返回值类型相同
  • 方法引用语法格式

         格式:类名 :: 静态方法

                范例:Integer :: parseIn

        格式:类名 :: new

                范例:Student :: new

        格式:对象 :: 成员方法

                范例:hello :: toUpperCase

        格式:this :: 方法名 / super :: 方法名

五、方法引用示例

1、静态方法引用

1.1、定义Calcable接口类

package tech.flygo.lambda.demo6;/*** @description: 计算数值接口* @author: flygo* @time: 2023/8/12 11:16*/
@FunctionalInterface
public interface Calcable {/*** description: 定义一个抽象方法,传递一个整数,对整数进行绝对值计算并返回 <br>* date: 2023/8/12 11:17 <br>* author: flygo <br>** @return int* @param: number*/int calcAbs(int number);
}

1.2、定义StaticMethodReference主函数测试类

package tech.flygo.lambda.demo6;/*** @description: 通过类名引用静态成员方法 <br>* 类已经存在,静态成员方法也已经存在 <br>* 就可以通过类名直接引用静态成员方法 <br>* @author: flygo* @time: 2023/8/12 11:18*/
public class StaticMethodReference {/*** description: 定义一个方法,方法的参数传递要计算绝对值的整数,和函数式接口Calcable <br>* date: 2023/8/12 11:19 <br>* author: flygo <br>** @return int* @param: number* @param: c*/public static int method(int number, Calcable c) {return c.calcAbs(number);}public static void main(String[] args) {// 调用method方法,传递计算绝对值的整数和Lambda表达式int number = method(-10, (n) -> {// 对参数进行绝对值计算并返回结果return Math.abs(n);});System.out.println(number);// 使用方法引用优化Lambda表达式/*** Math类是存在的* abs计算绝对值的静态方法也是存在的* 所有我们可以直接通过类名引用静态方法*/int result = method(-20, Math::abs);System.out.println(result);}
}

1.3、代码示例

2、构造方法引用

2.1、定义Person类

package tech.flygo.lambda.demo7;/*** @description: 人类* @author: flygo* @time: 2023/8/12 11:45*/
public class Person {private String name;public Person() {}public Person(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

2.2、定义一个创建Person对象的函数式接口

package tech.flygo.lambda.demo7;/*** @description: 定义一个创建Person对象的函数式接口* @author: flygo* @time: 2023/8/12 11:47*/
@FunctionalInterface
public interface PersonBuilder {/*** description: 定义一个方法,根据传递的姓名,创建Person对象返回 <br>* date: 2023/8/12 11:48 <br>* author: flygo <br>** @return tech.flygo.lambda.demo7.Person* @param: name*/Person buildPerson(String name);
}

2.3、定义ConstructorMethodReference主函数测试类

package tech.flygo.lambda.demo7;/*** @description: 类的构造器(构造方法)引用* @author: flygo* @time: 2023/8/12 11:49*/
public class ConstructorMethodReference {/*** description: 定义一个方法,参数传递姓名和PersonBuilder接口,方法中通过姓名创建Person对象 <br>* date: 2023/8/12 11:50 <br>* author: flygo <br>** @return void* @param: name* @param: builder*/public static void printName(String name, PersonBuilder builder) {Person person = builder.buildPerson(name);System.out.println(person.getName());}public static void main(String[] args) {// 调用printName方法,方法的参数PersonBuilder接口是一个函数式接口,可以传递Lambda表达式printName("刘德华", name -> new Person(name));// 使用方法引用优化Lambda表达式/**构造方法 new Person(String name)已知创建对象已知 new就可以使用Person引用new创建对象*/// 使用Person类带参数的构造方法,通过传递的姓名创建对象printName("周欣欣", Person::new);}
}

2.4、代码示例和运行结果

3、普通方法引用

3.1、定义一个打印的函数式接口Printable

package tech.flygo.lambda.demo8;/*** @description: 定义一个打印的函数式接口* @author: flygo* @time: 2023/8/12 12:14*/
@FunctionalInterface
public interface Printable {/*** description: 定义打印字符串的抽象方法 <br>* date: 2023/8/12 12:15 <br>* author: flygo <br>** @return void* @param: s*/void print(String s);
}

3.2、打印字符串的对象类MethodRerObject

package tech.flygo.lambda.demo8;/*** @description: 打印字符串的对象类* @author: flygo* @time: 2023/8/12 12:15*/
public class MethodRerObject {/*** description: 定义一个成员方法,传递字符串,把字符串转换成大写输出 <br>* date: 2023/8/12 12:16 <br>* author: flygo <br>** @return void* @param: str*/public void printUpperCaseString(String str) {System.out.println(str.toUpperCase());}
}

3.3、通过对象名引用成员方法测试类

package tech.flygo.lambda.demo8;/*** @description: 通过对象名引用成员方法* 使用前提是对象名是已经存在的,成员方法也是已经存在的* 就可以使用对象名来引用成员方法* @author: flygo* @time: 2023/8/12 12:17*/
public class ObjectMethodReference {/*** description: 定义一个方法,方法的参数传递Printable接口 <br>* date: 2023/8/12 12:20 <br>* author: flygo <br>** @return void* @param: printable*/public static void printString(Printable printable) {printable.print("Hello");}public static void main(String[] args) {// 调用printString方法,方法的参数Printable是一个函数式接口,所以可以传递Lambda表达式printString(s -> {// 创建MethodRerObject对象MethodRerObject object = new MethodRerObject();// 调用MethodRerObject对象中的成员方法printUpperCaseString,把字符串按照大写输出object.printUpperCaseString(s);});// 创建MethodObject对象MethodRerObject object = new MethodRerObject();/*使用方法引用优化Lambda对象是已经存在的MethodRerObject成员方法是已经存在的printUpperCaseString所以可以使用对象名引用尘缘方法*/printString(object::printUpperCaseString);}
}

3.4、示例代码和运行结果

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DBeaver配置类Navicat显示字段是否非空

在Navicat中设计表时可以很方便的看到字段是否【非空】&#xff0c;而在DBeaver中确实这样显示的,必须双击字段才能看到是否【非空】 解决方案 点击此处齿轮按钮,将【非空】以及其他需要的显示字段都勾上,重新打开即可

Python中的有序字典是什么

有序字典 一、简介 Python中的字典的特性&#xff1a;无序性。 有序字典和通常字典类似&#xff0c;只是它可以记录元素插入其中的顺序&#xff0c;而一般字典是会以任意的顺序迭代的。 二、普通字典 #! /usr/bin/env python3 # -*- coding:utf-8 -*- d1 {} d1[a] A d1[b…

【Java EE初阶七】多线程案例(生产者消费者模型)

1. 阻塞队列 队列是先进先出的一种数据结构&#xff1b; 阻塞队列&#xff0c;是基于队列&#xff0c;做了一些扩展&#xff0c;适用于多线程编程中&#xff1b; 阻塞队列特点如下&#xff1a; 1、是线程安全的 2、具有阻塞的特性 2.1、当队列满了时&#xff0c;就不能往队列里…

druid Communications link failure报错处理

现象 日志报错&#xff1a;com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 原因 从数据库连接池拿到了已经关闭的连接&#xff0c;导致报错。druid有定时任务进行空闲连接的检测和回收&#xff0c;当连接时长超过mysql的连接超时时间…

YOLOv8改进 | 2023主干篇 | FasterNeT跑起来的主干网络( 提高FPS和检测效率)

一、本文介绍 本文给大家带来的改进机制是FasterNet网络,将其用来替换我们的特征提取网络,其旨在提高计算速度而不牺牲准确性,特别是在视觉任务中。它通过一种称为部分卷积(PConv)的新技术来减少冗余计算和内存访问。这种方法使得FasterNet在多种设备上运行速度比其他网络…

【Flink精讲】Flink数据延迟处理

面试题&#xff1a;Flink数据延迟怎么处理&#xff1f; 将迟到数据直接丢弃【默认方案】将迟到数据收集起来另外处理&#xff08;旁路输出&#xff09;重新激活已经关闭的窗口并重新计算以修正结果&#xff08;Lateness&#xff09; Flink数据延迟处理方案 用一个案例说明三…

C# Attribute特性实战(1):Swtich判断优化

文章目录 前言简单Switch问题无参Swtich方法声明Swtich Attribute声明带有Swtich特性方法主方法结果 有参Switch修改代码修改运行过程运行结果 总结 前言 在经过前面两章内容的讲解&#xff0c;我们已经简单了解了如何使用特性和反射。我们这里解决一个简单的案例 C#高级语法 …

摄像头视频录制程序使用教程(Win10)

摄像头视频录制程序-Win10 &#x1f957;介绍&#x1f35b;使用说明&#x1f6a9;config.json 说明&#x1f6a9;启动&#x1f6a9;关闭&#x1f6a9;什么时候开始录制&#xff1f;&#x1f6a9;什么时候触发录制&#xff1f;&#x1f6a9;调参 &#x1f957;介绍 检测画面变化…

前端Web系统架构设计

文章目录 1.目录结构定义2. 路由封装2.1 API路由定义2.2 组件路由定义 3. Axios请求开发4. 环境变量封装5. storage模块封装(sessionStorage, localStorage)6. 公共函数封装(日期,金额,权限..)7. 通用交互定义(删除二次确认,类别,面包屑...)8. 接口全貌概览 1.目录结构定义 2. …

30、共空间模式CSP与白化矩阵

CSP算法和PCA降维都涉及到了白化&#xff0c;那白化的目的和作用到底是啥呢&#xff1f; 矩阵白化目的&#xff1a; 对于任意一个矩阵X&#xff0c;对其求协方差&#xff0c;得到的协方差矩阵cov(X)并不一定是一个单位阵。 下面介绍几个线代矩阵的几个概念&#xff1a; 1、…

计算机网络——OSI参考模型

1. OSI模型的基本概念 1.1 定义 OSI&#xff08;开放式系统互联&#xff09;模型是一个用于理解和标准化电信系统或计算机网络功能的概念性的框架&#xff0c;用于描述和标准化不同计算机系统或网络设备间通信的功能。 1.2 OSI模型的性质 这个模型由国际标准化组织&#xff08…

CMake入门教程【核心篇】定义C++宏定义(add_compile_definitions)

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「本文的内容」:CMake入门教程 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 1.基本用法2.定义单个宏3.定义多个宏4.条件定义宏5.使用预定义变量6.使用 generator 表达式