【Java8 重要特性】Lambda 表达式
文章目录
- Lambda
- 函数式接口
- Lambda 规则规范
- 简化过程
- 改写 Arrays.setAll()
- 改写 Arrays.sort()
- forEach
- 循环 list 集合
- 循环 list 集合并输出对象信息
- 循环 Map 集合
- 方法引用和构造器引用
- 方法引用
- 构造器引用
Lambda
Lambda是一个匿名函数,我们可以将Lambda表达式理解为一段可以传递的代码(将代码像数据一样传递)。使用它可以写出简洁、灵活的代码。作为一种更紧凑的代码风格,使 java 语言表达能力得到提升。
基本语法
(parameters) -> expression
或
(parameters) -> { statements }
函数式接口
函数式接口:只包含一个抽象方法的接口,并且可以使用 Lambda 表达式来创建该接口的对象。
- 函数式接口: 有且仅有一个抽象方法的接口
- Java 中的函数式编程体现就是 Lambda 表达式
- 所以函数式接口即可以适用于 Lambda 使用的接口
public static void main(String[] args) {//使用匿名函数new Thread(new Runnable(){@Overridepublic void run(){System.out.println("我是没有使用Lambda表达式:不简洁");}}).start();
}//使用Lambda表达式new Thread(() -> System.out.println("我是使用Lambda表达式:简洁、灵活")).start();
}
可以在任意函数式接口上使用 @FunctionalInterface 注解,来检测它是否是符合函数式接口。同时 javac 也会包含一条声明,说明这个接口是否符合函数式接口。
// 通过
@FunctionalInterface
public interface Lock {public abstract String lockUp(String str1,String str2); //上锁// public abstract void openLock(); //开锁
}
// 报错
@FunctionalInterface
public interface Lock {public abstract String lockUp(String str1,String str2); //上锁public abstract void openLock(); //开锁
}
注意:自定义函数式接口时,@FunctionalInterface是可选的,就算不写这个注解,只要保证满 足函数式接口定义的条件,也照样是函数式接口。
Lambda 规则规范
Lambda 表达式在 java 语言中引入了一种新的语法元素和操作。这种操作符号为 “->” ,Lambda 操作符或箭头操作符,它将 Lambda 表达式分割为两部分。
- 左边:指 Lambda 表达式的所有参数
- 右边:指 Lambda 体,即表示 Lambda 表达式需要执行的功能
Lambda表达式省略规则
1.Lambda的标准格式(参数类型1 参数名1, 参数类型2 参数名2) -> {...方法体的代码...return 返回值;}
2.在标准格式的基础上()中的参数类型可以直接省略,因为编译器可以推断得出,称为“类型推断”(参数名1, 参数名2) -> {...方法体的代码...return 返回值;}
3.如果{}总的语句只有一条语句,则{}可以省略、return关键字、以及最后的“;”都可以省略(参数名1, 参数名2) -> 结果
4.如果()里面只有一个参数,则()可以省略参数名 -> 结果
简化过程
只有基于函数式接口的匿名内部类才能被 Lambda 表达式简化。下面使用 Lambda 简化函数式接口,改写 Arrays 方法代码。
改写 Arrays.setAll()
setAll 用于对数组进行批量更新。其作用是根据给定的函数更新数组中的每个元素。
语法如下:
public static <T> void setAll(T[] array, IntFunction<? extends T> generator)
array: 要更新的数组generator: 一个IntFunction,根据数组的索引生成新的值
需求如下:把所有元素 * 0.8
public class LambdaTest {public static void main(String[] args) {double[] prices = {99.8, 128, 100};//1.先用匿名内部类写法Arrays.setAll(prices, new IntToDoubleFunction() {@Overridepublic double applyAsDouble(int value) {// value = 0 1 2return prices[value] * 0.8;}});//2.使用Lambda表达式标准写法Arrays.setAll(prices, (int value) -> {return prices[value] * 0.8;});//3.使用Lambda表达式简化格式1——省略参数类型Arrays.setAll(prices, (value) -> {return prices[value] * 0.8;});//4.使用Lambda表达式简化格式2——省略()Arrays.setAll(prices, value -> {return prices[value] * 0.8;});//5.使用Lambda表达式简化格式3——省略{}Arrays.setAll(prices, value -> prices[value] * 0.8 );System.out.println(Arrays.toString(prices));}
}
改写 Arrays.sort()
sort 方法用于对数组进行排序
语法如下:
public static <T> void sort(T[] a, Comparator<? super T> c)
a: 要排序的对象数组c: 自定义的比较器(Comparator)
需求如下:对数组中的元素按照年龄升序排列
public class LambdaTest2 {public static void main(String[] args) {Student[] students = new Student[4];students[0] = new Student("张三", 169.5, 23);students[1] = new Student("李四", 163.8, 26);students[2] = new Student("王五", 163.8, 26);students[3] = new Student("赵六", 167.5, 24);//1.先用匿名内部类写法Arrays.sort(students, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return Double.compare(o1.getHeight(), o2.getHeight()); // 升序}});//2.使用Lambda表达式标准格式Arrays.sort(students, (Student o1, Student o2) -> {return Double.compare(o1.getHeight(), o2.getHeight()); // 升序});//3.使用Lambda表达式简化格式1——省略参数类型Arrays.sort(students, ( o1, o2) -> {return Double.compare(o1.getHeight(), o2.getHeight()); // 升序});//4.使用Lambda表达式简化格式3——省略{}Arrays.sort(students, ( o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()));System.out.println(Arrays.toString(students));}
}
forEach
forEach 是 Java 8 引入的一种简洁的方式,用于遍历集合中的每个元素。它是 Collection 接口和 Map 接口中的一个默认方法,支持函数式编程风格。forEach 方法可以与 Lambda 表达式或方法引用结合使用,简化了传统的迭代代码。
forEach 方法的定义如下:
void forEach(Consumer<? super T> action);
Consumer: 函数式接口,表示接受一个输入参数并对其进行操作而没有返回结果T: 集合中元素的类型
循环 list 集合
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.forEach(s -> System.out.println(s));
循环 list 集合并输出对象信息
public class UserVo {private String userName;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}
}
List<UserVo> list = new ArrayList<UserVo>();
list.add(new UserVo());
list.add(new UserVo());
list.add(new UserVo());
list.forEach(s -> System.out.println(s.getUserName()));
循环 Map 集合
Map<String, UserVo> map = new HashMap<String, UserVo>();
map.put("A", new UserVo());
map.put("B", new UserVo());
map.put("C", new UserVo());
使用传统 forEach 循环
for (Map.Entry<String, UserVo> entry : map.entrySet()) {System.out.println(entry.getKey() + ":" + entry.getValue().getUserName());
}
使用 lambda 表达式
map.forEach(new BiConsumer<String, UserVo>() {@Overridepublic void accept(String k, UserVo v) {System.out.println(k + ":" + v.getUserName());}
});
简写
map.forEach((k,v) -> System.out.println(k + ":" + v.getUserName()));
方法引用和构造器引用
方法引用
当要传递给 Lambda 体的操作已经有实现方法,可以直接使用方法引用(实现抽象方法的列表,必须要和方法引用的方法参数列表一致)
方法引用使用操作符 :: 将方法名和类或者对象分割开来
有下列三种情况:
对象::实例方法
类::实例方法
类::静态方法
@FunctionalInterface
public interface Lock {public abstract void lockUp(String str); //上锁
}
Lock lock = System.out::println;
lock.lockUp("测试......");
构造器引用
本质上构造器引用和方法引用相似,只是使用了一个 new 方法
使用说明:函数式接口参数列表和构造器参数列表要一致,该接口返回值类型也是构造器返回值类型
格式:ClassName :: new
@FunctionalInterface
public interface Lock {public abstract String lockUp(String str); //上锁
}
// 非构造器引用
Lock lock1 = (s) -> new String(s);
// 构造器引用
Lock lock2 = String::new;
相关文章:
【Java8 重要特性】Lambda 表达式
文章目录 Lambda函数式接口Lambda 规则规范简化过程改写 Arrays.setAll()改写 Arrays.sort() forEach循环 list 集合循环 list 集合并输出对象信息循环 Map 集合 方法引用和构造器引用方法引用构造器引用 Lambda Lambda是一个匿名函数,我们可以将Lambda表达式理解为…...
word2vec--CBOW与Skip-Gram 两种模型
Word2Vec 是一种流行的用于生成词嵌入(Word Embeddings)的无监督学习模型,它由 Google 的一个团队在 2013 年提出。它的主要目的是将单词映射到一个连续的向量空间,使得语义相似的单词在这个空间中靠得更近。 Word2Vec 有两种主要…...
iOS六大设计原则设计模式
六大设计原则: 一、单一职责原则 一个类或者模块只负责完成一个职责或者功能。 类似于:UIView 和 CALayer 二、开放封闭原则 对扩展开放,对修改封闭。 我们要尽量通过扩展软件实体来解决需求变化,而不是通过修改已有的代码来…...
nacos 集群搭建
主机准备 IProle192.168.142.155slave02192.168.142.156slave192.168.142.157master 三台主机上分别构建 mysql 镜像 FROM mysql:8.0.31 ADD https://raw.githubusercontent.com/alibaba/nacos/develop/distribution/conf/mysql-schema.sql /docker-entrypoint-initdb.d/nac…...
STM32快速复习(十二)FLASH闪存的读写
文章目录 一、FLASH是什么?FLASH的结构?二、使用步骤1.标准库函数2.示例函数 总结 一、FLASH是什么?FLASH的结构? 1、FLASH简介 (1)STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分&…...
漏洞扫描工具使用
首先把补丁的两个文件复制下来替换原文件 找到C:\ProgramData\Acunetix\shared\license然后替换 然后打开漏扫工具并刷新页面 然后添加要扫描的网站 等他扫描完成 扫描完成就可以生成报告了 一共五十多页的报告...
C++ | Leetcode C++题解之第424题替换后的最长重复字符
题目: 题解: class Solution { public:int characterReplacement(string s, int k) {vector<int> num(26);int n s.length();int maxn 0;int left 0, right 0;while (right < n) {num[s[right] - A];maxn max(maxn, num[s[right] - A]);i…...
利士策分享,动摇时刻的自我救赎
利士策分享,动摇时刻的自我救赎 在人生的长河中,我们每个人都会面临各种挑战与抉择, 那些让人心生动摇的瞬间,如同夜空中偶尔掠过的乌云,遮蔽了前行的星光。 但正是这些动摇,构成了我们成长的轨迹&#x…...
动手学深度学习(李沐)PyTorch 第 1 章 引言
在线电子书 深度学习介绍 安装 使用conda环境 conda create -n d2l-zh python3.8 pip安装需要的包 pip install jupyter d2l torch torchvision下载代码并执行 wget https://zh-v2.d2l.ai/d2l-zh.zip unzip d2l-zh.zip jupyter notebookpip install rise如果不想使用jupyt…...
二叉树(二)深度遍历和广度遍历
一、层序遍历 广度优先搜索:使用队列,先进先出 模板: 1、定义返回的result和用于辅助的队列 2、队列初始化: root非空时进队 3、遍历整个队列:大循环while(!que.empty()) 记录每层的size以及装每层结果的变量&a…...
【算法——双指针】
922. 按奇偶排序数组 II 算法讲解050【必备】双指针技巧与相关题目_哔哩哔哩_bilibili main:vector<int>nums { 3,1,2,4 };int i 0, j 1;int n nums.size() - 1;while (j < nums.size() && i < nums.size()) //如果奇偶任一方排好了,另…...
Rocky Linux 9 中添加或删除某个网卡的静态路由的方法
使用ip命令配置临时路由 添加静态路由 ip route add <目的网络> via <下一跳IP> dev <网卡接口名称>例: 给eth0网卡添加一个到达 192.168.2.0/24 网络,下一跳为 192.168.1.254 的路由 ip route add 192.168.2.0/24 via 192.168.1.254 dev eth0…...
网站建设中常见的网站后台开发语言有哪几种,各自优缺点都是什么?
市场上常见的网站后台开发语言有PHP、Python、JavaScript、Ruby、Java和.NET等。这些语言各有其独特的优缺点,适用于不同的开发场景和需求。以下是对这些语言的具体介绍: PHP 优点:PHP是一种广泛用于Web开发的动态脚本语言,特别适…...
【程序大侠传】应用内存缓步攀升,告警如影随形
前序 在武侠编码的江湖中,内存泄漏犹如隐秘杀手,潜伏于应用程序的各个角落,悄无声息地吞噬着系统资源。若不及时发现和解决,必将导致内存枯竭,应用崩溃。 背景:内存泄漏的由来 内存泄漏,乃程序…...
JavaWEB概述
JavaWEB概述 一、什么是JavaWEB 用Java技术解决web互联网领域的技术栈。要学习JavaWEB首先得知道什么是客户端和服务端 客户端:简而言之,这就是使用方,比如我们下载一个软件去使用,里面有很多我们可以使用的功能,那…...
半结构化知识抽取案例
半结构化知识抽取是指从半结构化数据源(如HTML、XML、JSON等)中提取有用的信息,并将其转换为更易于理解和使用的知识形式。半结构化数据通常包含一些结构化的标记或标签,但不像完全结构化的数据那样严格。 比如抽取如下网页到neo …...
Oracle Truncate和delete的区别
DropTruncatedelete语句类型 DDl (数据定义语言 Data Definition Language DDl (数据定义语言 Data Definition Language DML(数据操作语言 Data Manipulation Language 速度 快 删除整个表 快 一次性删除 慢 逐行删除 回滚不可不可可del…...
应用层协议 --- HTTP
序言 在上一篇文章中,我们在应用层实现了一个非常简单的自定义协议,我们在我们报文的首部添加了报文的长度并且使用特定的符号分割。但是想做一个成熟,完善的协议是不简单的,今天我们就一起看看我们每天都会用到的 HTTP协议 。 UR…...
网卡Network Interface Card
文章目录 网卡(Network Interface Card,简称NIC)是一种计算机硬件设备,用于将计算机连接到计算机网络,使计算机能够进行数据通信。它是计算机与外部网络(如局域网、互联网)之间的接口࿰…...
9.1 Linux_I/O_基本知识
文件类型 一切I/O皆文件,文件就是存放在磁盘上面的有序数据的集合。 文件类型: 常规文件 r :就是普通文件目录文件 d :就是目录,是一个索引字符设备文件 c :键盘、鼠标块设备文件 b :U盘、磁…...
AI应用开发利器:ai-devkit工具包核心功能与工程实践指南
1. 项目概述与核心价值最近在折腾AI应用开发,发现一个挺有意思的项目,叫codeaholicguy/ai-devkit。乍一看名字,你可能会觉得这又是一个“AI开发工具包”,市面上类似的工具已经多如牛毛了。但深入用下来,我发现它不太一…...
SAP KO88结算时,如何用BADI_FINS_ACDOC_POSTING_EVENTS把成本中心塞进自定义字段?
SAP KO88结算实战:通过BADI_FINS_ACDOC_POSTING_EVENTS实现成本中心到自定义字段的精准映射 在SAP工单结算(KO88)的复杂业务场景中,财务凭证的标准化字段往往无法满足企业多维度的分析需求。特别是当需要将特定成本中心信息映射到…...
QKeyMapper深度解析:现代输入设备管理系统的架构揭秘与实战指南
QKeyMapper深度解析:现代输入设备管理系统的架构揭秘与实战指南 【免费下载链接】QKeyMapper [按键映射工具] QKeyMapper,Qt开发Win10&Win11可用,不修改注册表、不需重新启动系统,可立即生效和停止。支持游戏手柄映射到键鼠&a…...
从零构建可定制对话系统:模块化架构与RAG实战指南
1. 项目概述:从零构建一个可定制的对话系统最近在折腾一个挺有意思的东西,我把它叫做“定制化聊天系统”。起因很简单,市面上现成的聊天机器人,无论是开源的还是商业的,总感觉差了那么点意思。要么是功能太臃肿&#x…...
STM8硬件IIC驱动BNO055传感器避坑指南(附完整代码)
STM8硬件IIC驱动BNO055传感器实战解析与优化 BNO055作为一款集成了9轴传感器融合算法的智能芯片,能够直接输出姿态角数据,极大简化了嵌入式系统中姿态解算的复杂度。然而在实际应用中,许多开发者发现使用STM32等常见MCU的模拟IIC接口难以稳定…...
PCL2启动器离线登录按钮消失?5分钟快速修复指南
PCL2启动器离线登录按钮消失?5分钟快速修复指南 【免费下载链接】PCL Minecraft 启动器 Plain Craft Launcher(PCL)。 项目地址: https://gitcode.com/gh_mirrors/pc/PCL 你是否遇到过PCL2启动器离线登录按钮突然消失的困扰࿱…...
Claude-Code-KnowCraft:轻量级代码知识库构建与智能问答实践
1. 项目概述与核心价值最近在跟几个做AI应用开发的朋友聊天,大家普遍有个痛点:想把Claude这类大语言模型(LLM)的能力深度集成到自己的代码库分析工具里,但发现现有的方案要么太重,要么太浅。太重的是指那些…...
基于RP2040与I2C总线打造可编程合成器吉他:从硬件到固件的完整实践
1. 项目概述:打造你的第一把可编程合成器吉他 如果你对电子音乐制作和嵌入式硬件开发都感兴趣,那么将两者结合的DIY项目无疑是最迷人的领域。今天要分享的,就是基于Adafruit RP2040 PropMaker Feather微控制器,从零开始打造一把功…...
Python Reddit数据采集与分析实战:从API调用到舆情监控
1. 项目概述与核心价值最近在开源社区里,一个名为openshrug/reddit-intel的项目引起了我的注意。乍一看,这像是一个针对 Reddit 平台的数据抓取或分析工具,但深入探究后,我发现它的定位远不止于此。它更像是一个为开发者、数据分析…...
【最新v2.7.1 版本安装包】OpenClaw 小白入门必看,零基础无需命令零代码保姆级教学
OpenClaw v2.7.1 一键安装部署教程|可视化傻瓜式搭建 ✨适配系统:Windows10/11 64 位 ✨当前版本:v2.7.1 版本(虾壳云版) ✨安装包大小:58.7MB 【点击下载最新安装包】https://xiake.yun/api/download/…...
