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)提出的,亦称墨菲法则、墨菲…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
