Java8实战-总结11
Java8实战-总结11
- Lambda表达式
- 方法引用
- 管中窥豹
- 如何构建方法引用
- 构造函数引用
Lambda表达式
方法引用
方法引用让你可以重复使用现有的方法定义,并像Lambda
一样传递它们。在一些情况下,比起使用Lambda
表达式,它们似乎更易读,感觉也更自然。下面就是借助更新的Java 8 API
,用方法引用写的一个排序的例子:
先前:
3
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));
之后(使用方法引用和java.util.Comparator.comparing
):
inventory.sort (comparing(Apple::getWeight));
管中窥豹
为什么应该关心方法引用?方法引用可以被看作仅仅调用特定方法的Lambda
的一种快捷写法。它的基本思想是,如果一个Lambda
代表的只是“直接调用这个方法”,那最好还是用名称来调用它,而不是去描述如何调用它。事实上,方法引用就是让你根据已有的方法实现来创建Lambda
表达式。但是,显式地指明方法的名称,代码的可读性会更好。它是如何工作的呢?当需要使用方法引用时,目标引用放在分隔符::
前,方法的名称放在后面。例如,Apple::getWeight
就是引用了Apple类中定义的方法getWeight
。请记住,不需要括号,因为没有实际调用这个方法。方法引用就是Lambda
表达式(Apple a) -> a.getWeight()
的快捷写法。下表给出了Java 8
中方法引用的其他一些例子。
可以把方法引用看作针对仅仅涉及单一方法的Lambda的语法糖,因为你表达同样的事情时要写的代码更少了。
如何构建方法引用
方法引用主要有三类。
- 指向静态方法的方法引用(例如
Integer
的parseInt
方法,写作Integer::parseInt
)。 - 指向任意类型实例方法的方法引用(例如
String
的length
方法,写作String::length
)。 - 指向现有对象的实例方法的方法引用(假设有一个局部变量
expensiveTransaction
用于存放Transaction
类型的对象,它支持实例方法getValue
,那么你就可以写expensiveTransaction::getValue
)。
第二种和第三种方法引用可能乍看起来有点儿晕。类似于string::length
的第二种方法引用的思想就是在引用一个对象的方法,而这个对象本身是Lambda
的一个参数。例如,Lambda
表达式(String s) -> .toUppeCase()
可以写作String::toUpperCase
。但第三种方法引用指的是,在Lambda
中调用一个已经存在的外部对象中的方法。例如,Lambda
表达式()->expensiveTransaction.getValue()
可以写作expensiveTransaction::getValue
。依照一些简单的方子,就可以将Lambda
表达式重构为等价的方法引用,如下图所示:
请注意,还有针对构造函数、数组构造函数和父类调用(super-call
)的一些特殊形式的方法引用。举一个方法引用的具体例子吧。比方说想要对一个字符串的List
排序,忽略大小写。List
的sort
方法需要一个Comparator
作为参数。在前面看到,Comparator
描述了一个具有(T, T)->int
签名的函数描述符。可以利用string
类中的compareToIgnoreCase
方法来定义一个Lambda
表达式(注意compareToIgnoreCase
是String
类中预先定义的)。
List<String> str = Arrays.asList("a","b","A","B");
str.sort((s1, s2)-> s1.compareToIgnorecase(s2));
Lambda
表达式的签名与Comparator
的函数描述符兼容。利用前面所述的方法,这个例子可以用方法引用改写成下面的样子:
List<String> str = Arrays.asList("a","b","A","B");
str.sort(String::compareToIgnoreCase);
请注意,编译器会进行一种与Lambda
表达式类似的类型检查过程,来确定对于给定的函数式接口,这个方法引用是否有效:方法引用的签名必须和上下文类型匹配。
测验:方法引用
下列Lambda表达式的等效方法引用是什么?
(1) Punction<String, Integer> stringToInteger = (String s) -> Integer.parseInt(s);(2)BiPredicatecList<String>, String> contains =(list, element) -> list.contains(element);答案如下。
(1)这个Lambda表达式将其参数传给了Integer的静态方法parseInt。这种方法接受一个需要解析的String,并返回一个Integer。因此,可以使用上图中的办法①(Lambda表达式调用静态方法)来重写Lambda表达式,如下所示:
Function<String, Integer> stringToInteger = Integer::parseInt;
(2)这个Lambda使用其第一个参数,调用其contains方法。由于第一个参数是List类型的,可以使用上图中的办法②,如下所示:
BiPredicate<List<String>, String> contains = List::contains;
这是因为,目标类型描述的函数描述符是(List<String>, String) -> boolean,而List::contains可以被解包成这个函数描述符。
到目前为止,只展示了如何利用现有的方法实现和如何创建方法引用。但是也可以对类的构造函数做类似的事情。
构造函数引用
对于一个现有构造函数,可以利用它的名称和关键字new
来创建它的一个引用:
ClassName::new
。它的功能与指向静态方法的引用类似。例如,假设有一个构造函数没有参数。
它适合Supplier
的签名() -> Apple
。可以这样做:
//构造函数引用指向默认的Apple()构造函数
Supplier<Apple> c1 = Apple::new;
Apple a1 = c1.get();
这就等价于:
//调用Supplier的get方法将产生一个新的Apple
//利用默认构造函数创建Apple的Lambda表达式
Supplier<Apple> c1 = () -> new Apple();
Apple a1 = c1.get();
如果构造函数的签名是Apple(Integer weight)
,那么它就适合Function
接口的签名,于是可以这样写:
//指向Apple(Integer weight)的构造函数引用
Function<Integer, Apple> c2 = Apple::new;
//调用该Function函数的apply方法,并给出要求的重量,将产生一个Apple
Apple a2 = c2.apply(110);
这就等价于:
用要求的重量创建一
个Apple的Lambda表
//用要求的重量创建一个Apple的Lambda表达式
FunctioncInteger,Apple> c2 =(weight)-> new Apple(weight);
//调用该Punction函数的apply方法,并给出要求的重量,将产生一个新的Apple对象
Apple a2 = c2.apply(110);
在下面的代码中,一个由Integer
构成的List
中的每个元素都通过前面定义的类似的map
方法传递给了Apple
的构造函数,得到了一个具有不同重量苹果的List
:
//将构造函数引用传递给map方法List<Integer> weights = Arrays.asList(7,3,4,10);List<Apple> apples = map(weights, Apple::new);public static List<Apple> map(List<Integer> list, Function<Integer, Apple> f) {List<Apple> result = new ArrayList<>();for(Integer e: list) {result.add(f.apply(e));}return result;}
如果有一个具有两个参数的构造函数Apple(String color, Integer weight)
,那么它就适合BiFunction
接口的签名,于是可以这样写:
//指向Apple(String color,Integer weight)的构造函数引用
BiPunction<String, Integer, Apple> c3 = Apple::new;
//调用该BiFunction函数的apply方法,并给出要求的颜色和重量,将产生一个新的Apple对象
Apple c3 = c3.apply("green", 110);
这就等价于:
//用要求的颜色和重量创建一个Apple的Lambda表达式
BiPunction<String, Integer, Apple> c3 = (color, weight) -> new Apple(color, weight);//调用该BiPunction函数的apply方法,并给出要求的颜色和重量,将产生一个新的Apple对象
Apple c3 = c3.apply("green", 110);
不将构造函数实例化却能够引用它,这个功能有一些有趣的应用。例如,可以使用Map
来将构造函数映射到字符串值。创建一个giveMeFruit
方法,给它一个String
和一个Integer
,它就可以创建出不同重量的各种水果:
static Map<String, Function<Integer, Fruit>> map = new HashMap<>();
static {map.put("apple", Apple::new);map.put("orange", Orange::new);// etc...
}//用map得到了一个Function<Integer, Fruit>
public static Fruit giveMeFruit(String fruit, Integer weight) {//用Integer类型的weight参数调用Function的apply()方法将提供所要求的Fruitreturn map.get(fruit.toLowercase()).apply(weight);
}
测验:构造函数引用
已经看到了如何将有零个、一个、两个参数的构造函数转变为构造函数引用。那要怎么样才能对具有三个参数的构造函数,比如Color(int,int,int),使用构造函数引用呢?答案:构造函数引用的语法是ClassName::new,那么在这个例子里面就是Color::new。但是需要与构造函数引用的签名匹配的函数式接口。
但是语言本身并没有提供这样的函数式接口,可以自己创建一个:
public interface TriFunction<T,U, V, R> {R apply(T t,U u,V v);
}
现在可以像下面这样使用构造函数引用了:
TriPunction<Integer, Integer, Integer, Color> colorFactory = Color::new;
相关文章:

Java8实战-总结11
Java8实战-总结11 Lambda表达式方法引用管中窥豹如何构建方法引用 构造函数引用 Lambda表达式 方法引用 方法引用让你可以重复使用现有的方法定义,并像Lambda一样传递它们。在一些情况下,比起使用Lambda表达式,它们似乎更易读,感…...
2023爱分析·低代码厂商全景报告|爱分析报告
关键发现 低代码开始向甲方核心场景渗透,呈现两个显著特征:“更深入”、“更垂直”。更深入,即甲方愈发注重低代码在复杂业务场景的应用开发能力;更垂直,即甲方需要使用低代码开发行业垂直应用,因此对行业或…...

视频两侧有黑边怎么处理?教你裁切视频黑边方法
现在的大多数电视是16:9的宽屏,而大多数视频都是4:3的标清或是16:9的高清。当你看一个标清或高清视频时,如果它的比例与你的电视屏幕比例不同,视频两侧就会出现黑边。这些黑边会对视频的质量或观看体验产生影响,那么怎么处理呢&am…...

如何设计一个Android端高性能日志监控系统
开发中客户端经常遇到一些线上问题, 无法复现, 但是又的的确确存在; 当线上反馈的时候无从下手; 主要是因为并不知道用户所处的环境,以及所做的操作顺序或者程序运行的顺序; 在排查问题和复现问题上占用了很大的成本; 如果debug时的log日志如果线上也能查看就好了; 基于此, 我们…...

maven下载按照及初次使用相关配置
maven下载按照及初次使用相关配置 一、下载 与安装 依赖Java,需要配置JAVA_HOME设置MAVEN自身的运行环境,需要配置MAVEN_HOME测试环境配置结果 MVN测试成功!!! 二、本地仓库配置 Maven启动后,会自动保…...
opencv05-掩膜
参考: https://blog.csdn.net/shuiyixin/article/details/88825549 #include <iostream> #include <opencv2/highgui/highgui.hpp> #include <opencv2/opencv.hpp> #include <vector> #include <array> #include <algorithm>u…...

通讯软件013——分分钟学会Kepware OPC AE Server仿真配置
本文介绍如何使用Kepware软件仿真OPC AE Server配置。相关软件可登录网信智汇(wangxinzhihui)下载。 1、创建1个数据源:本案例采用“Graybox.Simulator.1”作为数据源。连接OPC Server数据源“Graybox.Simulator.1”。 右键点击“连通性”&am…...

Windows下安装Hive(包安装成功)
Windows下安装Hive Hive与Hadoop的版本选择很关键,千万不能选错,否则各种报错。一、Hive下载1.1、官网下载Hive1.2、网盘下载Hive 二、解压安装包,配置Hive环境变量2.1、环境变量新增:HIVE_HOME2.2、修改Path环境变量,…...

count(列名) ,count(1)与count(*) 有何区别?
Mysql版本:8.0.26 可视化客户端:sql yog 文章目录 一、Mysql之count函数简介二、count(列名) ,count(常量)与count(*) 有何区别?2.1 统计字段上的区别2.2 执行效率上的区别 一、Mysql之count函数简介 👉表达式 COUNT(…...
node.js判断元素是否包括
在Node.js中,可以使用Array.prototype.some()方法来判断数组中是否包含某个元素。下面是一个示例代码: const arr [ { ‘_android:name’: ‘com.eg.android.AlipayGphone’ }, { ‘_android:name’: ‘com.eg.android.AlipayGphoneRC’ }, { ‘_andro…...

基于SpringBoot+Vue的地方废物回收机构管理系统设计与实现(源码+LW+部署文档等)
博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…...

【SAP MII学习】Day01--Overview, Security Services, and Workbench
1. Module 1: Overview 1.1 问题存在的原因 上图展示的是在工厂中IT的架构图,主要分为一下的三个层次: Shop Floor Automation and Control Systems (SFAC):collect data from the PLCs and sensors that are connected to the machinery on the facto…...
枚举类常见用法,A Guide to Java Enums
目录 啥是枚举类Custom Enum MethodsComparing Enum Types Using “” OperatorUsing Enum Types in Switch StatementsFields, Methods and Constructors in EnumsEnumSetEnumMapStrategy PatternSingleton PatternJava 8 and EnumsJSON Representation of EnumRead More Java…...
Vue Baidu Map--vue引入百度地图
1.安装 npm方式安装 $ npm install vue-baidu-map --save2.局部注册 <template> <div class"map-content" v-if"iscollegeRole"><baidu-map class"bm-view map":ak"mapAK" :scroll-wheel-zoom"true" :cen…...

使用Express部署Vue项目
使用Express部署Vue项目 目录 1. 背景 2. 配置Vue CLI 1.1 安装nodejs 1.2 创建vue-cli 1.3 创建vue项目 1.4 构建vue项目3. 配置Express 2.1 安装express 2.2 创建项目4. 使用express部署vue项目 1,背景 我们想要做一个前后端分离的课程项目,前端…...

344.翻转字符串+387.字符串中的第一个唯一字符
目录 一、翻转字符串 二、字符串中的第一个唯一字符 一、翻转字符串 344. 反转字符串 - 力扣(LeetCode) class Solution { public:void reverseString(vector<char>& s) {int start0;int end s.size()-1;while(start < end){swap(s[sta…...
安装mmcv
安装MMCV 创建虚拟环境gupao ,并激活nvcc -V 查看cuda版本 打开当前项目文件主页查看环境配置Prerequisites — MMPretrain 1.0.1 documentation 4. 安装合适的torch版本,原来的版本会自动卸载 pip install torch1.13.1cu117 torchvision0.14.1cu117 torch…...

什么是服务网格?
背景: 服务网格这个概念出来很久了,从 2017 年被提出来,到 2018 年正式爆发,很多云厂商和互联网企业都在纷纷向服务网格靠拢。像蚂蚁集团、美团、百度、网易等一线互联 网公司,都有服务网格的落地应用。服务网格是微服…...

8.1作业
文件IO函数实现拷贝文件。子进程先拷贝后半部分,父进程再拷贝前半部分,允许使用sleep函数 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<head.h> int main(int argc, const char *argv[]) {pid_t cpidfo…...

linux-安全技术
文章目录 安全机制墨菲定理信息安全防护的目标安全防护环节常见的安全攻击STRIDE 安全机制 墨菲定理 摘自百度百科 墨菲定律是一种心理学效应,1949年由美国的一名工程师爱德华墨菲(Edward A. Murphy)提出的,亦称墨菲法则、墨菲…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...