方法的引用第二版(method reference)

1、冗余的Lambda场景 

  • 在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿什么参数做什么操作。
  • 那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方在相同方案,那是否还有必要再写重复逻辑?
package com.methodreference;public class MethodReference {public static void main(String[] args) {printString((s) -> System.out.println(s));/*** 分析:*     Lambda表达式的目的,打印参数传递的字符串*     把参数s,传递给了System.out对象,调用out对象中的方法println对字符串进行了输出*     注意:*         1.System.out对象是已经存在的*         2.println方法也是已经存在的*     所以我们可以使用方法引用来优化Lambda表达式*     可以使用System.out方法直接引用(调用)println方法*/printString(System.out::println);}public static void printString(Printable p) {p.print("HelloWorld");}}@FunctionalInterface
interface Printable {void print(String s);
}

2、方法引用符

  • 双冒号::为引用运算符,而它所在的表达式被称为方法引用。如果Lambda要表达的函数方案已经存在于某个方法的实现中,那么则可以通过双冒号来引用该方法作为Lambda的替代者。

3、语义分析

        例如上例中,System.out对象中有一个重载的println(String)方法恰好九四我们所需要的。那么对于printString方法的函数式接口参数,对比下面两种写法,完全等效:

  • Lambda表达式写法:s  ->  System.out.println(s);
  • 方法引用写法:System.out : : println
  1. 第一种语言是指:拿到参数之后经Lambda之手,继而传递给System.out.println方法去处理。
  2. 第二种等效写法的语义是指:直接让System.out中的println方法来取代Lambda。两种写法的执行效果完全一样,而第二种方法引用的写法复用了已有方案,更加简介。

注意:Lambda中传递的参数一定是方法引用中的哪个方法可以接收的类型,否则会抛出异常

4、通过对象名引用成员方法 

  • 通过对象名引用成员方法
  • 使用前提是对象名是已经存在的,成员方法也是已经存在
  • 就可以使用对象名来引用成员方法
package com.methodreference;public class Demo01ObjectMethodReference {public static void main(String[] args) {printString(s -> {MethodRerObject obj = new MethodRerObject();obj.printUpperCaseString(s);});/*** 使用方法引用优化Lambda* 对象是已经存在的MethodRerObject* 成员方法也是已经存在printUpperCaseString* 所以我们可以使用对象名引用成员方法*/MethodRerObject obj = new MethodRerObject();printString(obj::printUpperCaseString);}public static void printString(Printable p) {p.print("Hello");}
}@FunctionalInterface
interface Printable {void print(String s);
}class MethodRerObject {public void printUpperCaseString(String str) {System.out.println(str.toUpperCase());}
}

 5、通过类名引用静态成员方法

  • 通过类名引用静态成员方法
  • 类已经存在,静态成员方法也已经存在
  • 就可以通过类名接引用静态成员方法
package com.methodreference;public class Demo01StaticMethodReference {public static int method(int number, Calcable c) {return c.calsAbs(number);}public static void main(String[] args) {int method = method(-10, (number) -> {return Math.abs(number);});System.out.println(method);//10/***  使用方法引用优化Lambda*  Math类是存在的*  abs计算绝对值的静态方法也是已经存在的*  所以我们可以直接通过类名引用静态方法*/int number2 = method(-20, Math::abs);System.out.println(number2);//20}}interface Calcable {int calsAbs(int number);
}

6、通过super引用父类的成员方法 

package com.methodreference;interface Greetable {void greet();
}
class Human {public void sayHello() {System.out.println("Hello我是Human!");}
}public class Man extends Human {@Overridepublic void sayHello() {System.out.println("Hello我是Man!");}public void method(Greetable g) {g.greet();}public void show() {
//        method(() -> {
//            Human h = new Human();
//            h.sayHello();
//        });/*** 因为有子父类关系,所以存在的一个关键字super,代表父类,* 所以我们可以直接使用super调用父类的成员方法*///        method(()->{
//            super.sayHello();
//        });/*** 使用super引用类的成员方法* super是已经存在的* 父类的成员方法sayHello也是已经存在的* 所以我们可以直接使用super引用父类的成员方法*/method(super::sayHello);}public static void main(String[] args) {new Man().show();}
}

 7、通过this引用本类的成员方法

package com.methodreference;public class Husband {public void buyHouse() {System.out.println("河南二环内买一套四合院!");}public void marry(Richable r) {r.buy();}public void soHappy() {
//        marry(()->{
//            this.buyHouse();
//        });/***  使用方法引用优化Lambda表达式*  this是已经存在的*  本类的成员方法buyHouse也是已经存在的*  所以我们可以直接使用this引用本类的成员方法buyHouse*/marry(this::buyHouse);//河南二环内买一套四合院!}public static void main(String[] args) {new Husband().soHappy();}}
@FunctionalInterface
interface Richable {void buy();
}

 8、类的构造器引用

package com.methodreference;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;}
}
@FunctionalInterface
interface PersonBuilder {Person builderPerson(String name);
}class Demo {public static void printName(String name,PersonBuilder pb) {Person person = pb.builderPerson(name);System.out.println(person.getName());}public static void main(String[] args) {printName("小明", (String name) -> {return new Person(name);});//小明/***  使用方法引用优化Lambda表达式*  构造方法new Person(String name)已知*  创建对象已知 new*  就可以使用Person引用new创建对象*/printName("小红",Person::new);//小红}
}

9、数组的构造器引用

package com.methodreference;import java.util.Arrays;public class Demo {public static int[] crateArray(int length,ArrayBuilder ab) {return ab.builderArray(length);}public static void main(String[] args) {int[] arr1 = crateArray(10, (length -> {return new int[length];}));System.out.println(arr1.length);/***  使用方法引用优化Lambda表达式*  已知创建的就是int[]数组*  数组的长度也是已知的*  就可以使用方法引用*  int[] 引用new,根据参数传递的长度来创建数组*/int[] arr2 = crateArray(20, int[]::new);System.out.println(Arrays.toString(arr2));System.out.println(arr2.length);}
}@FunctionalInterface
interface ArrayBuilder {int[] builderArray(int length);
}

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

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

相关文章

Swift的NSClassFromString转换

在swift 中使用NSClassFromString 从string 转换到 对象,报了Segmentation fault: 11 错误。 let ctrlClass: AnyClass NSClassFromString("HomeViewController")! let ctrl: UIViewController ctrlClass.init() as UIViewController 正确的写法&…

MATLAB制图代码【第二版】

MATLAB制图代码【第二版】 文档描述 Code describtion: This code is version 2 used for processing the data from the simulation and experiment. Time : 2023.9.3 Author: PEZHANG 这是在第一版基础上,迭代出的第二版MATLAB制图代码,第二版的特点是…

文献阅读:Semantic Communications for Speech Signals

目录 论文简介动机:为什么作者想要解决这个问题?贡献:作者在这篇论文中完成了什么工作(创新点)?规划:他们如何完成工作?自己的看法(作者如何得到的创新思路) 论文简介 作者 Zhenzi Weng Zhijin Qin Geoffre…

2023 AZ900备考

文章目录 如何学习最近准备考AZ900考试,找了一圈文档,结果发现看那么多文档,不如直接看官方的教程https://learn.microsoft.com/zh-cn/certifications/exams/az-900/ ,简单直接,突然想到纳瓦尔宝典中提到多花时间进行思…

linux安装firefox

1.下载对应包 https://www.mozilla.org/en-US/firefox/all/#product-desktop-release 2. 挂载桌面链接(如果/usr/bin/firefox下有的话,先删除) ln -s /opt/firefox/firefox /usr/bin/firefox 3.执行以下命令,即可启动Firefox客户端: firefox

Windows 重新映射 CapsLock 大写锁定到 Ctrl

Windows 重新映射 CapsLock 大写锁定到 Ctrl 本要点中的这些方法适用于我的美国键盘布局。我不确定其他布局。如果出现问题,请恢复您的更改;删除您创建的注册表项(并重新启动)。 强烈推荐 方法5 ctrl2cap,因为不会影…

《开发实战》14 | Spring框架:IoC和AOP是扩展的核心

14 | Spring框架:IoC和AOP是扩展的核心 IOC、AOP IoC,其实就是一种设计思想,为什么要让容器来管理对象呢?或许你能想到的是,使用 IoC 方便、可以实现解耦。但在我看来,相比于这两个原因,更重要…

Linux 基础篇

很长时间,因为一些事情,没有更新我的文章这让我很惭愧,于是我将打算在今天更新下自己的文章,我发现一些事情,计算机并不是很难学到可以工作的水平,关键在于是否可以坚持下来,有很多时候我并不是…

java项目mysql转postgresql

特殊函数 : mysql: find_in_set(?, ancestors) postgresql: ? ANY (string_to_array(ancestors,,)) mysql: date_format(t1.oper_time, %Y-%m-%d) postgresql: rksj::date to_char(inDate,YYYY-MM-DD) mysql&am…

vue中的nextTick的作用

vue里面,常用的事件onMounted里,总喜欢用一个nextTick: onMounted(() > {nextTick(() > {init();}); });这个东西有啥用呢?我总搞不懂。 今天我忽然有点明白了。这是一个跟前面语句有关的方法。意思是,等前面的…

Linux 配置Java 环境变量

1.修改 profile vim /etc/profile2.增加环境变量 # java env start export JAVA_HOME{java安装目录}export PATH$JAVA_HOME/bin:$PATHexport CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar # java env end3.刷新配置 source /etc/profile4.验证 echo $JAVA_H…

【Redis】Redis 的学习教程(七)之 SpringBoot 集成 Redis

在前几篇文章中,我们详细介绍了 Redis 的一些功能特性以及主流的 java 客户端 api 使用方法。 在当前流行的微服务以及分布式集群环境下,Redis 的使用场景可以说非常的广泛,能解决集群环境下系统中遇到的不少技术问题,在此列举几…

Vue.js安装步骤和注意事项

安装完node.js后开始安装和部署Vue在检查webpack的下载版本时出现错误出现错误的原因是之前下载时未指定对应的版本号导致版本不兼容先卸载掉之前下载的版本 cnpm uninstall webpack-cli -g cnpm install webpack-cli4.9.2 -g 最后检查版本是否对应

信息化发展19

数据结构模型 1 、数据结构模型是数据库系统的核心。数据结构模型描述了在数据库中结构化和操纵数据的方法, 模型的结构部分规定了数据如何被描述(例如树、表等)。模型的操纵部分规定了数据的添加、删除、显示、维护、打印、查找、选择、排序…

React:props说明

props是只读对象(readonly) 根据单项数据流的要求,子组件只能读取props中的数据,不能进行修改props可以传递任意数据 数字、字符串、布尔值、数组、对象、函数、JSX import FileUpdate from ./FileUpdate; export default class …

分数问题善用移项:0902T2

其实就是分数规划,但不完全是。 对于求 ∑ p i l i ∑ l i \Large\frac{\sum p_il_i}{\sum l_i} ∑li​∑pi​li​​ 在限定条件下的最大值,此类问题可以考虑二分答案并移项。 ∑ p i l i ∑ l i ≥ k \Large\frac{\sum p_il_i}{\sum l_i}\ge k ∑li​…

[dasctf]misc3 chrchrchr.pcapng

webshell 流量分析 php代码部分没啥看的,主要在标黄的部分,裁剪掉前面的字符可base解码 能看到在向a.txt中写入数据 wp # tshark.exe -r chrchrchr.pcapng -T fields -e urlencoded-form.value -Y "urlencoded-form.keyzd2ebbfb26dd" >…

【Linux】Libevent相关小知识总结

Libevent是基于事件的,也就是说,相当于去注册一个事件,当这个事件发生的话,那么就会调用回调函数。

8.(Python数模)马尔科夫链预测

Python实现马尔科夫链预测 马尔科夫链原理 马尔科夫链是一种进行预测的方法,常用于系统未来时刻情况只和现在有关,而与过去无关。 用下面这个例子来讲述马尔科夫链。 如何预测下一时刻计算机发生故障的概率? 当前状态只存在0(故…

windows环境装MailHog

背景:win10系统,windows 宝塔,laravel 项目,邮件相关需要装一个MailHog 下载地址:https://sourceforge.net/projects/mailhog.mirror/ 直接下载,下载后双击运行就可以了,系统可能提示”不信任“…