【数据结构】Lambda
⭐ 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:浅谈数据结构
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖
Lambda表达式
- 1. 背景
- 1.1 语法
- 1.2 函数式接口
- 2. 基本使用
- 3. 变量捕获
- 3.1 匿名内部类
- 3.2 匿名内部类的变量捕获
- 3.3 Lambda的变量捕获
- 4. Lambda在集合当中的使用
- 4.2 Collection接口
- 4.2 List接口
- 4.3 Map接口
1. 背景
lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。Lambda 表达式(Lambda expression),基于数学中的λ演算得名,也可称为闭包(Closure)。
1.1 语法
基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }
- paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明,也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。
- ->:可理解为“被用于”的意思
- 方法体:可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不返回,这里的代码块块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不返回。
// 1. 不需要参数,返回值为 2
() -> 2
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的和
(x, y) -> x + y
// 4. 接收2个int型整数,返回他们的乘积
(int x, int y) -> x * y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
1.2 函数式接口
函数式接口定义:一个接口有且只有一个抽象方法
- 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口
- 如果我们在某个接口上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接口,这样如果有两个抽象方法,程序编译就会报错的。所以,从某种意义上来说,只要你保证你的接口中只有一个抽象方法,你可以不加这个注解。加上就会自动进行检测的。
定义方式:
@FunctionalInterface
interface NoParameterNoReturn {//注意:只能有一个方法void test();
}
@FunctionalInterface
interface NoParameterNoReturn {void test();default void test2() {System.out.println("JDK1.8新特性,default默认方法可以有具体的实现");}
}
2. 基本使用
Lambda可以理解为:Lambda就是匿名内部类的简化,实际上是创建了一个类,实现了接口,重写了接口的方法。
先实现几个接口:
//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {void test();
}
//无返回值一个参数
@FunctionalInterface
interface OneParameterNoReturn {void test(int a);
}
//无返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {void test(int a,int b);
}
//有返回值无参数
@FunctionalInterface
interface NoParameterReturn {int test();
}
//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {int test(int a);
}
//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {int test(int a,int b);
}
Lambda的具体使用实例:
public class TestDemo1 {public static void main(String[] args) {NoParameterNoReturn noParameterNoReturn = ()->{System.out.println("无参数无返回值");};noParameterNoReturn.test();OneParameterNoReturn oneParameterNoReturn = (int a)->{System.out.println("一个参数无返回值:"+ a);};oneParameterNoReturn.test(10);MoreParameterNoReturn moreParameterNoReturn = (int a,int b)->{System.out.println("多个参数无返回值:"+a+" "+b);};moreParameterNoReturn.test(20,30);NoParameterReturn noParameterReturn = ()->{System.out.println("有返回值无参数!");return 40;};
//接收函数的返回值int ret = noParameterReturn.test();System.out.println(ret);OneParameterReturn oneParameterReturn = (int a)->{System.out.println("有返回值有一个参数!");return a;};ret = oneParameterReturn.test(50);System.out.println(ret);MoreParameterReturn moreParameterReturn = (int a,int b)->{System.out.println("有返回值多个参数!");return a+b;};ret = moreParameterReturn.test(60,70);System.out.println(ret);}
}

3. 变量捕获
3.1 匿名内部类
匿名内部类就是没有名字的内部类。在Java的匿名类中,会存在变量捕获。
匿名内部类不能定义任何静态成员、方法。
匿名内部类中的方法不能是抽象的.
匿名内部类必须实现接口或抽象父类的所有抽象方法.
匿名内部类访问的外部类成员变量或成员方法必须用static修饰.
匿名内部类的使用示例:
class Test{public void func(){System.out.println("func()");}
}public class TestDemo {public static void main(String[] args) {new Test(){@Overridepublic void func() {System.out.println("我是内部类,且重写了func这个方法!");}};}
}
3.2 匿名内部类的变量捕获
class Test {public void func(){System.out.println("func()");}
}public class TestDemo {public static void main(String[] args) {int a = 100;new Test(){@Overridepublic void func() {System.out.println("我是内部类,且重写了func这个方法!");System.out.println("我是捕获到变量 a == "+a
+" 我是一个常量,或者是一个没有改变过值的变量!");}};}
}
在上述代码当中的变量a就是,捕获的变量。这个变量要么是被final修饰,如果不是被final修饰的,你要保证在使用之前,没有修改。
如下代码就是错误的代码:
public class TestDemo {public static void main(String[] args) {int a = 100;new Test(){@Overridepublic void func() {a = 99;System.out.println("我是内部类,且重写了func这个方法!");System.out.println("我是捕获到变量 a == "+a
+" 我是一个常量,或者是一个没有改变过值的变量!");}};}
}
//该代码会直接编译报错
3.3 Lambda的变量捕获
@FunctionalInterface
interface NoParameterNoReturn {void test();
}public static void main(String[] args) {int a = 10;NoParameterNoReturn noParameterNoReturn = ()->{// a = 99; errorSystem.out.println("捕获变量:"+a);//也不允许修改};noParameterNoReturn.test();
}
4. Lambda在集合当中的使用
为了能够让Lambda和Java的集合类集更好的一起使用,集合当中,也新增了部分接口,以便与Lambda表达式对接。
| 对应的接口 | 新增的方法 |
|---|---|
| Collection | removeIf() spliterator() stream() parallelStream() forEach() |
| List | replaceAll() sort() |
| Map | getOrDefault() forEach() replaceAll() putIfAbsent() remove() replace() computeIfAbsent()computeIfPresent() compute() merge() |
4.2 Collection接口
forEach() 方法演示
该方法在接口 Iterable 当中,原型如下:
default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}
}
该方法表示:对容器中的每个元素执行action指定的动作 。
示例:
public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("world");list.add("hello");list.add("lambda");list.forEach(new Consumer<String>(){@Overridepublic void accept(String str){//简单遍历集合中的元素。System.out.print(str+" ");//Hello world hello lambda}});}
修改为Lambda表达式如下:
public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("world");list.add("hello");list.add("lambda");//表示调用一个,不带有参数的方法,其执行花括号内的语句,为原来的函数体内容。list.forEach(s -> {System.out.println(s);//Hello world hello lambda});}
4.2 List接口
sort()方法的演示
sort方法源码:该方法根据c指定的比较规则对容器元素进行排序。
public void sort(Comparator<? super E> c) {final int expectedModCount = modCount;Arrays.sort((E[]) elementData, 0, size, c);if (modCount != expectedModCount) {throw new ConcurrentModificationException();}modCount++;
}
使用示例:
public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("world");list.add("hello");list.add("lambda");list.sort(new Comparator<String>() {@Overridepublic int compare(String str1, String str2){//这里比较长度return str1.length()-str2.length();}});System.out.println(list);//[Hello, world,hello,lambda]}
修改为Lambda表达式如下:
public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("world");list.add("hello");list.add("lambda");//调用带有2个参数的方法,且返回长度的差值list.sort((str1,str2)-> str1.length()-str2.length());System.out.println(list);//[Hello, world,hello,lambda]}
4.3 Map接口
HashMap 的 forEach()
该方法原型如下:
default void forEach(BiConsumer<? super K, ? super V> action) {Objects.requireNonNull(action);for (Map.Entry<K, V> entry : entrySet()) {K k;V v;try {k = entry.getKey();v = entry.getValue();} catch(IllegalStateException ise) {// this usually means the entry is no longer in the map.throw new ConcurrentModificationException(ise);}action.accept(k, v);}
}
作用是对Map中的每个映射执行action指定的操作。
代码示例:
public static void main(String[] args) {HashMap<Integer, String> map = new HashMap<>();map.put(1, "hello");map.put(2, "world");map.put(3, "hello");map.put(4, "lambda");map.forEach(new BiConsumer<Integer, String>(){@Overridepublic void accept(Integer k, String v){System.out.println(k + "=" + v);}});}
//1=hello
//2=world
//3=hello
//4=lambda
修改为Lambda表达式:
public static void main(String[] args) {HashMap<Integer, String> map = new HashMap<>();map.put(1, "hello");map.put(2, "bit");map.put(3, "hello");map.put(4, "lambda");map.forEach((k,v)-> System.out.println(k + "=" + v));}
相关文章:
【数据结构】Lambda
⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:浅谈数据结构 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 Lambda表达式 1. 背景1.1 语法1.2 函…...
力扣labuladong——一刷day28
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣380. O(1) 时间插入、删除和获取随机元素二、力扣710. 黑名单中的随机数 前言 常数时间删除-查找数组中的任意元素,且随机访问概率一致 如果…...
2023年CCF非专业级别软件能力认证第二轮 (CSP-S)提高级C++语言试题
2023年CCF非专业级别软件能力认证第二轮 (CSP-S)提高级C语言试题 编程题第 1 题 问答题 密码锁(lock) 题目描述 小Y有一把五个拨圈的密码锁。如图所示,每个拨圈上是从0到9的数字。每个拨圈都是从0到9的循环…...
华为ensp:静态默认路由
静态路由 到r2 上的系统视图模式 下一跳为1.1.1.2 ip route-static 192.168.2.0 255.255.255.0 1.1.1.2 如果找2网段下一跳为1.1.1.2接口 默认路由 到r3上做的是默认路由 ip route-static 0.0.0.0 0 1.1.1.1 所有的流量去找1.1.1.1 查看效果 只要做完完整的路由就可…...
xss 通过秘籍
终极测试代码 <sCr<ScRiPt>IPT>OonN"\/(hrHRefEF)</sCr</ScRiPt>IPT> 第一关(没有任何过滤) 使用终极测试代码,查看源码 发现没有任何过滤,直接使用javascrupt中的alert弹框 <script>aler…...
Kibana使用Watcher监控服务日志并发送飞书报警(Markdown)
Watcher是什么 Kibana Watcher 是 Elasticsearch 的监控和告警工具,它允许你设置和管理告警规则以监控 Elasticsearch 数据和集群的状态。Kibana Watcher 可以监测各种指标和数据,然后在满足特定条件时触发警报。它提供了一种强大的方式来实时监控 Elas…...
Flutter笔记:光影动画按钮、滚动图标卡片组等
Flutter笔记 scale_design更新:光影动画按钮、滚动图标卡片组 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263…...
【论文】利用移动性的比例公平蜂窝调度测量和算法
(一支笔一包烟,一节论文看一天 )(一张纸一瓶酒,一道公式推一宿) 摘要1. 引言2. 相关工作3. 模型和问题公式4. 预测FPF调度 ( P F ) 2 S (PF)^2S (…...
内存条选购注意事项(电脑,笔记本)
电脑内存条的作用、选购技巧以及注意事项详解 - 郝光明的个人空间 - OSCHINA - 中文开源技术交流社区 现在的电脑直接和内存条联系 电脑上的所有输入和输出都只能依靠内存条 现在买双条而不是单条 买两个相同的内存条最好 笔记本先分清是低电压还是标准电压,DD…...
ChatGPT 宕机?OpenAI 将中断归咎于 DDoS 攻击
您的 ChatGPT 已关闭吗?您是否遇到 ChatGPT 问题,例如连接问题或遇到“长响应时出现网络错误”?– ChatGPT 遭受了一系列 DDoS 攻击,显然是由匿名苏丹组织策划的。 OpenAI 的 ChatGPT 是一款流行的人工智能聊天机器人,…...
go单元格测试
编写单元测试(Unit Test)是一种测试方法,用于验证代码中的单个功能单元(通常是函数或方法)是否按照预期工作。以下是编写单元测试的一般步骤: 1. 创建测试文件:在项目的测试目录中创建一个新的…...
JavaScript理解表达式和语句的含义
JavaScript中的表达式和语句都是用于完成特定计算或操作的语言构件,但它们有着不同的含义和用途: 表达式(expression)是用来计算并返回一个值的代码片段,可以包含变量、数值、函数调用、运算符等。表达式的运算结果可以被赋值给变量、作为函数…...
Visual Studio导入Wiinform项目文件,引用显示黄色感叹号
参考博客 第一步: 开程序包管理控制台 vs->工具->NuGet包管理器->程序包管理控制台 Update-Package –reinstall 第二步: 删除.csproj 文件片段 // 整个模块全部删除 包括标签中所含有的任何内容 <Target Name"EnsureNuGetPackage…...
深入研究SVN代码检查的关键工具:svnchecker vs. SonarQube,选择最适合你的代码检查工具
目录 一、SVN代码检查(整合svnchecker)1、创建SVN代码库2、下载安装包3、修改SVN配置4、新建代码检查配置文件(名称自定义)5、hooks目录添加配置文件6、设置只对Java文件进行检查7、测试 二、SonarQube代码检测1、什么是SonarQube2、MySQL数据库的安装3、SonarQube服务端软件安…...
博客积分上一万一千了
博客积分上一万一千了 充满自信,继续前进。...
docker 构建并运行 python项目
此处不重述docker安装及基本命令,可参考另一篇文章centos7 安装 docker_centos7 docker network rm-CSDN博客文章浏览阅读111次。1、 1.1 docker 官网 Empowering App Development for Developers | DockerLearn how Docker helps developers bring their ideas to …...
django建站过程(4)创建文档显示页面
django建站过程(4)创建文档显示页面 创建文档显示页面项目主文件夹schoolapps中的文件urls.py在APP“baseapps”中创建url.py文件编写视图模板继承bootstrap创建head.html创建doclist.html创建docdetail.html 使用 markdown 编辑器安装模块Model 模型的d…...
uniapp本地存储的几种方式
在UniApp中,你可以使用本地存储来保存和获取数据,以便在应用的不同页面之间共享数据或在应用关闭后仍然保存数据。UniApp提供了两种主要的本地存储方式:uni.setStorage 和 uni.getStorage,以及 uni.removeStorage 用于删除数据。这…...
74hc595模块参考
74hc595模块参考 8位串行并行输出(SIPO)移位寄存器 使用74HC595移位寄存器扩展微控制器上的输出引脚数量。如果你需要扩充输入引脚的数量那么你需要74HC165移位寄存器。 SER(串行输入)引脚用于一次一位地将数据发送到移位寄存器…...
【Unity细节】Failed importing package???Unity导包失败?
👨💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 😶🌫️收录于专栏:unity细节和bug 😶🌫️优质专栏 ⭐【…...
Unity自动寻路实战:用NavMeshAgent实现动态路径绘制(附完整Shader代码)
Unity动态路径可视化:用NavMeshAgent与Shader打造流动导航线 在角色扮演类游戏开发中,路径可视化不仅是功能需求,更是提升玩家体验的关键设计。当角色在复杂场景中自动寻路时,一条会"呼吸"的流动路径线,远比…...
解密GPCRs二级结合口袋:从β2AR到5HT2BR的偏置信号传导机制
解密GPCRs二级结合口袋:从β2AR到5HT2BR的偏置信号传导机制 在结构药理学领域,G蛋白偶联受体(GPCRs)的配体结合机制研究一直是药物开发的核心课题。传统研究多聚焦于正位结合位点(Orthosteric Binding Site, OBS),而近年来,二级结…...
基于PID的四旋翼无人机轨迹跟踪控制 0. 直接运行simulink仿真文件.slx 1
基于PID的四旋翼无人机轨迹跟踪控制0. 直接运行simulink仿真文件.slx 1. 如果出现文件或变量不能识别的警告或错误,建议将文件夹添加到matlab搜索路径以检索到所需文件,或者进入到最里层文件夹运行程序。 2. 如果想去掉simulink模块的封面图(…...
FastAPI项目半夜报警吵醒你?聊聊告警这事儿怎么搞!焉
Issue 概述 先来看看提交这个 Issue 的作者是为什么想到这个点子的,以及他初步的核心设计概念。?? 本 PR 实现了 Apache Gravitino 与 SeaTunnel 的集成,将其作为非关系型连接器的外部元数据服务。通过 Gravitino 的 REST API 自动获取表结构和元数据&…...
ros2中可视化topic数值命令
ros2 run plotjuggler plotjuggler...
挂起、阻塞、锁和cpu占用
Thread.sleep() 和 Object.wait() 在 Java 多线程编程中,Thread.sleep() 和 Object.wait() 都能让线程暂停执行,但它们的目的机制和使用场景有本质区别。核心区别总结所属类不同sleep() 是 Thread 类的静态方法,作用于当前线程。…...
如何快速掌握Node.js最佳实践:2024终极指南
如何快速掌握Node.js最佳实践:2024终极指南 【免费下载链接】nodebestpractices :white_check_mark: The Node.js best practices list (July 2024) 项目地址: https://gitcode.com/GitHub_Trending/no/nodebestpractices Node.js最佳实践项目是Node.js开发者…...
2025届最火的十大AI科研网站实测分析
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 日益广泛应用于学术写作领域的人工智能技术,,特别适用于开题报告的辅…...
告别手动搬运:利用Gitee镜像功能实现GitHub仓库的自动同步
1. 为什么需要自动化同步GitHub和Gitee仓库 作为一个经常在GitHub和Gitee双平台托管代码的开发者,我深刻理解手动同步的痛苦。每次在GitHub上提交代码后,都要记得去Gitee手动更新,稍不留神就会忘记,导致两个平台的代码版本不一致。…...
Coze插件开发实战:如何将现有API快速封装并发布到扣子商店
1. 从零开始理解Coze插件开发 第一次接触Coze插件开发时,我也被各种概念绕得头晕。简单来说,这就像给手机安装APP——扣子商店是应用市场,插件就是里面的各种APP。而我们要做的,就是把自家开发的API服务打包成这样一个"APP&q…...
