你是不是足够了解Lambda表达式?

兰布达表达式 lambad表达式学习基础,示例快速了解兰布达表达式在代码中的应用 立即下载

前言

Lambda 表达式(Lambda Expression),相信大家对 Lambda 肯定是很熟悉的,毕竟我们数学上经常用到它,即 λ 。不过,感觉数学中的 Lambda 和编程语言中的 Lambda 表达式没啥关系,要说有关系就是都有 Lambda 这个词,噢!当然还有一个关系就是 Lambda 演算。

λ 演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义、函数如何被应用以及递归的形式系统。它由数学家阿隆佐·邱奇在20世纪30年代首次发表。lambda演算作为一种广泛用途的计算模型,可以清晰地定义什么是一个可计算函数,而任何可计算函数都能以这种形式表达和求值,它能模拟单一磁带图灵机的计算过程。

回到编程语言这方面,其实不只是 Java 引入了这个 Lambda 表达式,其他编程语言也有,比如 C++、Javascript、Python 等等。当然,本篇文章回顾的是 Java 中的 Lambda 表达式。

作为一个初学者,下面对于 Lambda 的理解肯定不够严谨,甚至可能包含错误,望观众老爷们能在评论区指出!

为什么要学这个 Lambda 表达式?

  1. Java 8 的新特性,简化代码的编写。

  2. 工作中会用到,防止看不懂别人写的代码。

  3. 大家都学我也学。

什么是 Lambda 表达式?

Lambda 表达式是一个匿名函数,换句话说,你有匿名函数,那么它这个函数就是所谓的 Lambda 表达式。

所谓匿名函数,顾名思义,就是没有函数名的函数。

那么肯定有小伙伴会说,没有函数名,那我怎么调用这个函数啊?

是的,这个问题问得很好,先保持这个疑问!在回答这个问题之前,我先来说说另一个概念——「函数式编程」。

什么是函数式编程?

函数式编程是一种编程范式,除此之外,还有声明式编程、命令式编程,也都是编程范式。

好吧,这里又扯出一个新的专业名词——「编程范式(Programming Paradigm)」。范式?相信正在阅读的你,在学习数据库知识的时候,肯定学过第一范式、第二范式、第三范式,那现在又有一个编程范式,这是什么鬼?

百度百科是这样说的:

编程范型、编程范式或程序设计法(英语:Programming paradigm),(范即模范、典范之意,范式即模式、方法),是一类典型的编程风格,是指从事软件工程的一类典型的风格(可以对照方法学)。如:函数式编程、程序编程、面向对象编程、指令式编程等等为不同的编程范型。

是不是太官方了,没关系,简单理解,我认为知道函数式编程是一种写代码时的风格就OK了。

我们需要注意的是,函数式编程中的「函数」二字,是数学上的函数,并不是我们现在习惯理解的函数,也就是说,这是纯纯数学概念上的函数,即自变量的映射,比如 y=f(x)y = f(x)y=f(x),自变量 xxx,通过函数 fff 映射成 yyy 。

函数式编程和 Lambda 表达式有什么关系?

可以说,函数式编程允许使用一种表达式来表示一个函数,这种表达式就是 Lambda 表达式。

在 Java 中,函数式编程是通过一个接口规范来实现的,接口具有这种特点:

  • 该接口有且只有一个抽象方法

  • 该接口使用 @FunctionalInterface 注解进行标识

具有这个特点的接口称为「函数式接口」。

现在,回到最开始说的,「没有函数名,那我怎么调用这个函数啊?」,这就是函数式接口的用途了,接口中只有一个抽象方法,不用指定方法名称,就能够用 Lambda 表达式来调用这个函数(方法)了,不需要知道函数名就能够实现调用。好比想在某个房间(接口)找个人(方法)来做事,我这个房间只有一个人,那么除了这个人,没有其他人可以来做事了,就不需要指定那谁谁谁过来帮忙,而是直接喊:就决定是你了!(这个比喻可能也不是很恰当,当大概意思是这样哈哈哈)

函数式接口

Comparator

我们可以看看 Comparator 接口,它有 @FunctionalInterface 注解,那么可以肯定它是一个函数式接口。

@FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); default Comparator<T> reversed() { return Collections.reverseOrder(this); } default Comparator<T> thenComparing(Comparator<? super T> other) { Objects.requireNonNull(other); return (Comparator<T> & Serializable) (c1, c2) -> { int res = compare(c1, c2); return (res != 0) ? res : other.compare(c1, c2); }; } ... } 复制代码

有小伙伴应该要说了,这个接口这么多方法,为什么还能是函数式接口?

注意了啊,我们可以看到一个好像是抽象的 equals 方法,但是,因为 equals 是 Object 中的方法,这种对Object 类的方法的重新声明是会让方法变成一个具体的方法。所以,不要误会了,这里的抽象方法就只有 compare 方法。

那可能有小伙伴要说了,接口中还能有具体的方法?

是的,没错,在 Java 8 中,接口中可以写具体的方法了。比如上面的 reversed 和 thenComparing 方法,都是具体的方法。

常见的函数式接口

  • java.lang.Runnable

@FunctionalInterface public interface Runnable { public abstract void run(); } 复制代码
  • java.util.concurrent.Callable

@FunctionalInterface public interface Callable<V> { V call() throws Exception; } 复制代码
  • java.lang.reflect.InvocationHandler

@FunctionalInterface public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; } 复制代码

如何使用 Lambda 表达式?

在 Java 8 之前,我们使用 Collections 的需要比较器的 sort 方法,是这样的。

等等,忘了有比较器参数的 sort 方法了?没关系,代码给你贴上:

public static <T> void sort(List<T> list, Comparator<? super T> c) { list.sort(c); } 复制代码

最开始的写法是这样的,由于 Comparator 是一个接口,不能直接实例化,所以需要一个类来实现这个接口作为真正的比较器类,然后将这个 Comparator 实例对象作为 sort 方法第二个参数传入,实现排序,如下:

public class KeyComparator implements Comparator<Integer> { @Override public int compare(Integer v1, Integer v2) { return v1 - v2; } } List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); Collections.sort(keys, new KeyComparator()); System.out.println(keys); // [2, 3, 5, 9, 10] 复制代码

后来,这种写法比较麻烦,于是用匿名内部类改写这种写法,我们不需要自己去编写一个类来实现这个接口了,直接用匿名内部类。就是这种写法:

List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); Collections.sort(keys, new Comparator<Integer>() { @Override public int compare(Integer v1, Integer v2) { return v1 - v2; } }); System.out.println(keys); // [2, 3, 5, 9, 10] 复制代码

现在,匿名内部类比起 Lambda 表达式,也是麻烦,我们用 Lambda 进行改写:

List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); Collections.sort(keys, (Integer v1, Integer v2) -> {return v1 - v2;}); System.out.println(keys); // [2, 3, 5, 9, 10] 复制代码

是吧,(Integer v1, Integer v2) -> {return v1 - v2;} 的写法,没有函数名,也能进行调用。

实际上,这样还不是最简的,最简的是这样:(v1, v2) -> v1 - v2

是不是很好奇啥时候能这样写?现在就告诉你!

基本语法

(参数类型 参数名) -> { 方法体 }

基本上,这样写,是不会有问题的。下面说说何时能写得更加简单。

为了便于阅读,下面的「方法」指的是函数式接口中的抽象方法

  • 方法没有参数,那么可以直接写小括号,然后箭头,再写中括号,最后写方法体,即 () -> { 方法体 }

  • 方法有多个参数,那么多个参数就用逗号分开,同时参数类型是可以省略的,即 (v1, v2, ...) -> {方法体}

  • 方法只有一个参数,那么小括号可以去掉,直接写参数名,然后箭头,再中括号和方法体,即 v -> {方法体}

  • 方法体只有一条语句,无论是否有返回值,都可以省略大括号、return 关键字及语句分号。

情况一:方法无参数、无返回值

常见的就是 Runnable 接口了。

@FunctionalInterface public interface Runnable { public abstract void run(); } 复制代码
  • 未使用 Lambda(使用匿名内部类):

new Thread(new Runnable() { @Override void run() { System.out.println("线程开始跑了"); } }).start(); 复制代码
  • 使用 Lambda:

// 写法一 new Thread(() -> { System.out.println("线程开始跑了") }).start(); // 写法二,一条语句,那么省略大括号、return 关键字及语句分号 new Thread(() -> System.out.println("线程开始跑了")).start(); 复制代码

情况二:方法无参数,有返回值

例子:Callable 接口

@FunctionalInterface public interface Callable<V> { V call() throws Exception; } 复制代码
  • 未使用 Lambda(使用匿名内部类):

FutureTask<String> stringFutureTask = new FutureTask<>(new Callable<String>() { @Override public String call() throws Exception { return "这里是返回值"; } }); stringFutureTask.run(); System.out.println(stringFutureTask.get()); 复制代码
  • 使用 Lambda:

// 一条语句,省略大括号、return 关键字及语句分号 FutureTask<String> stringFutureTask = new FutureTask<>(() -> "这里是返回值"); stringFutureTask.run(); System.out.println(stringFutureTask.get()); 复制代码

情况三:方法一个参数、有返回值

我随便找了 JDK 中的一个接口,如下:

@FunctionalInterface interface Recognizer { boolean recognize(int c); } 复制代码
  • 未使用 Lambda(使用匿名内部类):

private final Recognizer A = new Recognizer() { @Override public boolean recognize(int c) { return c == 'a' || c == 'A'; } } 复制代码
  • 使用 Lambda:

private final Recognizer A = (c) -> c == 'a' || c == 'A'; // 一个参数,可省略小括号 private final Recognizer A = c -> c == 'a' || c == 'A'; 复制代码

情况四:方法多个参数、有返回值

直接举 Comparator 这个例子。

  • 未使用 Lambda(使用匿名内部类):

List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); keys.sort(new Comparator()<Integer> { @Override public int compare(Integer v1, Integer v2) { return v1 - v2; } }); 复制代码
  • 使用 Lambda:

List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); // 多个参数以逗号分开,可省略类型,一条语句,省略大括号、return 关键字及语句分号 keys.sort((v1, v2) -> v1 - v2); System.out.println(keys); 复制代码

总结

到这里,相信大家对于 Lambda 表达式有了一个基本的认识。总的来说:

  • 必须是函数式接口才能使用 Lambda 表达式

语法:(参数类型 参数名称) ‐> { 方法体 }

  • 若方法的参数列表: 没有参数,则可直接用 () ; 有一个参数,可以省略 (),直接写参数; 有多个参数,则()不可省略 () 内的参数类型可以省略

  • 若方法体: 只有一条语句,无论是否有返回值,都可以省略大括号、return 关键字及语句分号。 处理逻辑过于臃肿复杂,还是使用具体子类改写较好,保证可读性。

6层高速PCB设计实战:BGA布局与阻抗匹配关键解析 本文深入解析6层高速PCB设计中BGA布局与阻抗匹配的关键技术。通过实战经验分享,详细介绍了六层PCB层叠结构的选择与优化、BGA器件布局技巧、阻抗匹配的实战经验以及高速布线技巧,帮助工程师提升PCB设计水平,确保信号完整性和电源完整性。 阅读详情

相关推荐

深入浅出:CosineLRScheduler 调度器的原理与实战应用

本文深入解析了CosineLRScheduler调度器的核心原理与实战应用,详细介绍了余弦退火算法及其在深度学习模型训练中的优势。通过参数配置建议、PyTorch实现示例和常见问题解决方案,帮助开发者高效应用该调度器提升模型性能,特别适用于计算机视觉和自然语言处理任务。

sss66的博客 859

Lambda 表达式

一.什么事Lambda表达式 Lambda 表达式是一种匿名函数,也可称为闭包,简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。 它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使 Java 语言的表达能力得到了提升。 二.Lambda表达式的语法 lambda 表达式的语法格式如下: (parameters) -> expression 或 (par...

xxdw1992的博客 1万+

携程酒店数据爬取进阶:动态接口破解与反反爬策略实战

本文详细解析了携程酒店数据爬取的进阶技巧,包括动态接口参数破解、反爬虫策略对抗及企业级采集方案实现。重点介绍了eleven参数的生成逻辑、动态Cookie维护方法,以及如何应对携程的请求指纹检测和行为模式识别。通过实战案例,帮助开发者高效获取酒店价格数据,同时遵守行业规范。

eee77的博客 1081

Lambda表达式

文章目录1.什么是Lambda表达式2.为什么使用Lambda表达式3.Lambda表达式语法4.函数式接口4.1 什么是函数式接口4.2 自定义函数式接口4.3 Java内置函数式接口5.方法引用6.构造器引用7.数组引用8.Lambda表达式的作用域8.1 访问局部变量8.2 访问局部引用,静态变量,实例变量8.3 Lambda表达式访问局部变量作限制的原因9.Lambda表达式的优缺点 1.什么是Lambda表达式 Lambda表达式,也可称为闭包。类似于JavaScript中的闭包,它是推动Java

小赵的呢 7085

LVGL嵌入式GUI工程化架构与多窗口实践

嵌入式GUI开发中,LVGL作为轻量级图形库,其核心价值在于高效渲染与事件驱动机制。理解LVGL的对象树模型、资源管理机制(如RAW图像、静态字体)和屏幕生命周期,是构建稳定界面的基础。结合FreeRTOS等实时操作系统,可实现低功耗、高响应的交互体验。典型应用场景包括智能电表、HMI人机界面、工业控制面板等对内存敏感、需长期运行的设备。本文以微信式多窗口架构为范例,深入解析LVGL工程化落地的关键路径:分层目录结构、窗口模块封装、状态机式登录逻辑、TabView多页导航及图表/仪表盘动态可视化,覆盖从资源

weixin_36001279的博客 94

Allegro基本规则设置指导书之Analysis Modes

On-line DRC是需要开启的,否则所有DRC都不起作用。调出Analysis Modes,这个是所有DRC的总开关。默认是关闭的,可以用来检查孔是否打在SMD的pin上的情况。器件超出package keepin的DRC开关。所有间距相关的DRC开关都要打开。Pad和Pad连接的DRC开关。测试点Pad到器件DRC开关。测试点在器件下方的DRC开关。阻焊到Pad和线的DRC开关。阻焊到shape的DRC开关。下面介绍常用的一些开关设置。器件在器件禁布的DRC开关。测试点到器件的DRC开关。

weixin_54787054的博客 3544

C++兰不达表达式

#include <functional> #include <iostream> #include<vector> #include<algorithm>using namespace std;void main1() { auto fun1 = {cout << “hello” << endl; };auto fun2 = [](int a,int b){return a+b; };

wright_hash的博客 1047

[EdgeAI] NXP eIQ 机器学习Toolkit (二):模型篇

eIQ™机器学习(ML)软件开发环境支持在恩智浦EdgeVerse™微控制器和微处理器(包括i.MX RT跨界MCU和i.MX系列应用处理器)上使用ML算法。eIQ ML软件包括称为eIQ Toolkit的ML工作流工具以及推理引擎、神经网络编译器和优化库。......

HowieXue 薛永浩的博客 1万+

C++11:lambda表达式

通常lambda表达式用于封装一些传递给算法或异步函数的代码。C++11中引入了λ表达式,它可以用来定义一个**内联 (inline)**的函数,作为一个本地的对象或者一个参数。内联函数是一种编译器优化技术,它可以避免函数调用的开销,提高执行效率。λ表达式可以被编译器自动内联展开,从而减少函数调用的次数。但是,并不是所有的λ表达式都会被内联,这取决于编译器的实现和优化策略。

Man9o 1万+

通过Simulink搭建一个智能微电网能量管理系统(Energy Management System, EMS)

通过上述代码实现,您可以逐步创建一个智能微电网能量管理系统。多源能量集成:整合光伏、风力发电、柴油发电机、电池储能等多种能源资源。负荷预测与调度:基于历史数据和天气预报,预测未来负荷和可再生能源输出,进行优化调度。储能系统优化:设计合理的充放电策略,确保储能系统的高效利用和寿命延长。经济性分析:评估不同运行模式下的经济性,考虑电价、维护成本等因素。环境影响评估:分析微电网对环境的影响,如减少碳排放、提高可再生能源利用率等。硬件在环仿真(HILS)

amy_mhd的博客 314

基于SpringBoot 3 + Vue 3的全栈民宿预约管理系统设计与实现

文章将详细阐述系统的需求分析、架构设计、数据库设计、核心功能模块的实现(包括用户认证、房源管理、订单流程、支付集成等),并提供关键代码片段,最后对系统进行总结与展望。.requestMatchers("/api/admin/**").hasRole("ADMIN") // 管理员接口。.requestMatchers("/api/auth/**").permitAll() // 认证接口公开。.requestMatchers("/api/public/**").permitAll() // 公开资源。

2201_76125393的博客 273

C# Lambda表达式

C#,Lambda表达式

鲤籽鲲的博客 1万+

07 Zabbix 微信告警

Zabbix 微信告警 1.注册企业微信 企业微信注册地址:https://work.weixin.qq.com 2.进入企业微信后台管理 2.1 添加微信成员 2.2创建应用 2.3 获取四项数据 (1)AgentID (2) Secret (3) 企业ID (4)部门ID 3.Zabbix Server配置 3.1确认脚本目录 # grep alertscripts /etc/zabbix/zabbix_server....

Jian Sun_的博客 1300

详解Lambda表达式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、什么是面向接口编程?一、什么是Lambda表达式?1.Lambda表达式使用前提:二、使用步骤1.引入库2.读入数据1、抽象方法2、翻译为Lambda表达式标准格式3、Lambda表达式的上下文推断1、推断条件2、推断条件三、Lambda表达式的使用(1) 根据赋值语句左侧的类型来进行Lambda上下文推断(2) Lambda表达式的简便写法 前言 一、什么是面向接口编程? 提示:这里可以添加本文要记录的大概内容: 例如:

weixin_44811903的博客 3万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

大哥了解一下Lambda表达式

1.什么是Lambda表达式? Lambda表达式是JDK1.8开始之后的新技术,是一种代码的新语法。 是一种特殊写法,“核心目的是为了简化匿名内部类的代码写法”。2.Lambda表达式的格式: (匿名内部类被重写方法的形参列表) -> { 被重写方法的方法体代码。 } -> 就是一个新语法,没有实际含义,但是不能省略!3.Lambda表达式简化匿名内部类的前提: Lambda表达式并不是能简化所有匿名内部类代码的写法。 Lambda表达式只能简化函数式接口的匿...

print的博客 8195

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

你对lambda表达式的使用方法以及底层原理了解吗?

Lambda表达式是Java编程语言中引入的一种函数式编程的特性,它可以用更简洁的方式来表示匿名函数。Lambda表达式可以作为一种行内函数,用于替代传统的匿名内部类。其中,parameters表示Lambda表达式的参数列表,可以为空或包含一个或多个参数。箭头符号->将参数列表与表达式或代码块进行分隔。如果Lambda表达式只有一条表达式,可以直接写表达式;如果Lambda表达式需要执行多条语句,则需要使用代码块{}来包裹语句。

热爱技术,享受生活 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Lambda表达式到底是什么?——简单了解Lambda表达式

一、Lambda表达式是什么 简单来说,Lambda表达式是一个可传递的代码段。可以不借助对象传递的一个代码段。那java中为什么要加入这么一个特性呢? 二、为什么使用Lambda表达式 从一个简单的例子开始。 比如现在有一个Person类 package POJO; import lombok.Data; import java.util.Objects; /** * @author wangtianqi * @create 2020-08-19 15:59 */ @Data public

TIANQIcode 1449

了解Java Lambda表达式

文章目录1. 什么是函数接口?示例1:在java中定义函数接口示例2:使用Java中的匿名类实现SAM2. Lambda表达式简介2.1 如何在Java中定义Lambda表达式?2.2 Lambda主体的类型示例3:Lambda表达式3. 带参数的Lambda表达式示例4:使用带参数的lambda表达式4. 通用函数接口示例5:泛型函数接口和Lambda表达式6. Lambda表达式和流API示例6:将lambdas与流API一起使用的演示参考文档     在本文中,我们将通过示例了解java lambda

运维狗的备忘录 266

java Lambda表达式的使用

如题,因为博主也是最近才接触到Lambda表达式的(PS 在这里汗颜一会)。我并不会讲解它的原理,诚然任何一件事物如果理解原理的话,使用它必将更加容易。但博主在学习的时候,大多数时候都是学会怎么用,然后在细究原理。就像你骑自行车之前,难道首先还要研究自行车的原理么?首先Lambda表达式的最简单应用如下 String lam= "初次相识Lambda"; new Th...

知我饭否 7837

反射、枚举及lambda表达式

java提供的反射机制是一把双刃剑,它打破了我们对原有访问修饰限定符的认知。枚举是一个特殊的类,可以将一些可能出现的情况枚举出来,以便于我们使用。lambda表达式是对代码的一种简写,可以让代码足够简单。

小小太空人的博客 1833

了解下Lambda表达式

JDK的升级的目的有以下几个:增加新的功能、修复bug、性能优化、简化代码等几个方面,Lambda表达式就是属于简化代码,用于简化匿名实现类,提供一种更加简洁的写法。Lambda表达式在Swift语言中称之为代码块,Lambda表达式可以认为是一种特殊的接口,该接口必须只有一个抽象方法。 语法 (参数类型 参数名, 数参数类型 参数名2...) -> { // code}; 小括号()中的内容就是方法中的参数列表包括参数类型、参数名,其中参数类型是可以省略的,当参数个数只有一个时也可以省略掉

dongbeiou的专栏 452

Lambda表达式及其优势

.NET 3.5中委托的写法(Lambda表达式)Lambda表达式在C#中的写法是“arg-list => expr-body”,“=>”符号左边为表达式的参数列表,右边则是表达式体(body)。参数列表可以包含0到多个参数,参数之间使用逗号分割。例如,以下便是一个使用Lambda表达式定义了委托的示例1:Funcint, int, int> max = (int a, int b)

Kasbaster的专栏 2万+
上一篇: 万字文带你搞懂Java线程池原理是什么
下一篇: 为什么在公司里访问不了家里的电脑?
Java_LingFeng
博客等级 码龄4年 505粉丝 259原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值