【响应式编程-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、示例代码和运行结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构第八弹---队列

队列 1、队列的概念和结构2、队列的实现2.1、头文件包含和结构定义2.2、初始化2.3、销毁2.4、判断是否为空2.5、入队2.6、出队2.7、获取队头数据2.8、获取队尾数据2.9、获取有效数据个数 3、代码汇总总结 1、队列的概念和结构 队列&#xff1a;只允许在一端进行插入数据操作&am…

给定0-1数组,找出连续1最长和次最长的2个子数组的起始位置和结束位置。

题目 给定0-1数组&#xff0c;找出连续1最长和次最长的2个子数组的起始位置和结束位置。 要求&#xff1a; 子数组长度大于等于1。 如果有多个子数组满足条件&#xff0c;按照数组下标由小到大只输出满足条件的前2个数组的起始位置和结束位置&#xff0c; 如果只有1个满足&…

Multisim各版本安装指南

Multisim下载链接 https://pan.baidu.com/s/1En9uUKafhGOqo57V5rY9dA?pwd0531 1.鼠标右击【Multisim 14.3(64bit)】压缩包&#xff08;win11及以上统需先点击“显示更多选项”&#xff09;选择【解压到 Multisim 14.3(64bit)】。 2.打开解压后的文件夹&#xff0c;双击打开【…

深度学习中的知识蒸馏

一.概念 知识蒸馏&#xff08;Knowledge Distillation&#xff09;是一种深度学习中的模型压缩技术&#xff0c;旨在通过从一个教师模型&#xff08;teacher model&#xff09;向一个学生模型&#xff08;student model&#xff09;传递知识来减小模型的规模&#xff0c;同时保…

UAV | 多算法在多场景下的无人机路径规划(Matlab)

近年来&#xff0c;无人机(unmanned aerial vehicle&#xff0c;UAV)由于其灵活度高、机动性强、安全风险系数小、成本低等特点&#xff0c;被广泛应用于搜索巡逻、侦察监视、抢险救灾、物流配送、电力巡检、农业灌溉等军用或民用任务。路径规划是无人机执行任务的关键&#xf…

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

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

Spring依赖注入的魔法:深入DI的实现原理【beans 五】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Spring依赖注入的魔法&#xff1a;深入DI的实现原理【beans 五】 前言DI的基本概念基本概念&#xff1a;为什么使用依赖注入&#xff1a; 构造器注入构造器注入的基本概念&#xff1a;示例&#xff1a…

RK3568 学习笔记 : 解决 linux_sdk 编译 python 版本报错问题

前言 最近买了 【正点原子】 的 RK3568 开发板&#xff0c;下载了 开发板的资料&#xff0c;包括 Linux SDK&#xff0c;这个 Linux SDK 占用的空间比较大&#xff0c;扩展了一下 VM 虚拟机 ubuntu 20.04 的硬盘空间&#xff0c;编译才正常通过。 编译 RK3568 Linux SDK 时&am…

二维地图组件开发

很多的业务项目中&#xff0c;都会用到二维地图&#xff0c;二维地图功能简洁&#xff0c;并且很多在很多的业务中采用&#xff0c;维护难度也比三维地图小一些。而开发二维地图的开源库有QGis&#xff0c; Mapwingis等。 采用mapwingis开发了一个二维地图组件&#xff0c;可以…

Jmeter事务控制器聚合报告

Jmeter 事务控制器。 在Jmeter中&#xff0c;默认一个取样器就是一个事务 事务控制器控制其子集取样器&#xff0c;合并为一个事务 添加&#xff1a;逻辑控制器/Logic Controller -> 事务控制器/Transaction Controller TPS: 服务器每秒处理的事务数 在事务控制器下添加多…

Http与Tcp协议的原理以及应用

OSI七层模型和相关协议 七层模型从上到下如下所示&#xff1a; 应用层&#xff1a;负责应用之间的通信&#xff0c;处理请求和响应的具体格式表示层&#xff1a;对于数据格式进行处理会话层&#xff1a;负责建立和断开通信连接&#xff0c;传输层&#xff1a;负责建立端口之间…

gdal平面几何空间关系

关于平面几何的空间关系判定&#xff0c;gdal提供了8个函数&#xff0c;分别是&#xff1a;Intersects&#xff08;相交&#xff09;&#xff0c;Equals&#xff08;相等&#xff09;&#xff0c;Disjoint&#xff08;不相交&#xff09;&#xff0c;Touches&#xff08;接触&a…

LeetCode做题总结 15. 三数之和、18. 四数之和 (Java)

不会做&#xff0c;参考了代码随想录和力扣官方题解&#xff0c;对此题进行整理。 X数之和 15. 三数之和代码思路20240103重写错误1错误2Java语言点总结 18. 四数之和代码思路20240104&#xff08;伪&#xff09;错误1 第一次剪枝错误2 第二次剪枝错误3 溢出 15. 三数之和 代码…

C#使用纯OpenCvSharp部署yolov8-pose姿态识别

【源码地址】 github地址&#xff1a;https://github.com/ultralytics/ultralytics 【算法介绍】 Yolov8-Pose算法是一种基于深度神经网络的目标检测算法&#xff0c;用于对人体姿势进行准确检测。该算法在Yolov8的基础上引入了姿势估计模块&#xff0c;通过联合检测和姿势…

vue icon 本地正常 线上打包失败变乱码

出现这个原因是因为sass解析的问题 Node版本高的话可以通过升级sass版本 并且配置vue.config规避这个问题 //给sass配置的东西 这个对应的版本是sass 1.39.0 本人node版本v14 升级sass版本后出现报错css: {loaderOptions: {scss: {additionalData: import "/styles/var…

网络请求 - 异步编程详解

一、概述 网络管理模块主要提供以下功能&#xff1a; HTTP数据请求&#xff1a;通过HTTP发起一个数据请求。WebSocket连接&#xff1a;使用WebSocket建立服务器与客户端的双向连接。Socket连接&#xff1a;通过Socket进行数据传输。 HTTP和WebSocket都是啥&#xff1f; 比如我…

速记计算机网络传输介质分类

计算机网络中的传输介质是指用于在不同设备之间传递数据的物理媒介。传输介质的选择对于网络的性能和可靠性至关重要。在计算机网络中&#xff0c;常见的传输介质可以分为有线传输介质和无线传输介质两类。本文将对这两类传输介质进行详细的分类和介绍。 一、有线传输介质 有…

外包干了4个月,技术退步明显了...

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01; 而我已经在一个企业干了四…

[C]jupyter中使用C

[C]jupyter中使用C 安装使用用处 安装 https://github.com/brendan-rius/jupyter-c-kernel 下拉找到3条命令&#xff0c;装就可以了 mac和linux可用 python3可用&#xff0c; 2不可以 第二条命令可以改为 : python3 install_c_kernel 小总结&#xff1a;如果有问题&#xff0…

Merge还是Rebase?这次终于懂了

《Git分支管理&#xff1a;Merge还是Rebase&#xff1f;》 导语&#xff1a; 在Git的分支管理中&#xff0c;Merge和Rebase是两种常见的合并策略&#xff0c;每一种都有其优劣之处。究竟应该选择Merge还是Rebase&#xff0c;取决于项目的需求和团队的工作流程。本文将深入探讨…