如何理解 Java 8 引入的 Lambda 表达式及其使用场景
Lambda表达式是Java 8引入的一项重要特性,它使得编写简洁、可读和高效的代码成为可能。Lambda表达式本质上是一种匿名函数,能够更简洁地表示可传递的代码块,用于简化函数式编程的实现。
一、Lambda表达式概述
1. 什么是Lambda表达式
Lambda表达式是一种匿名函数,表示一段可传递的代码块,能够接受参数并返回结果。它是一种函数式接口(Functional Interface)的实例。函数式接口是仅包含一个抽象方法的接口,例如Runnable、Callable、Comparator等。
Lambda表达式的引入旨在简化匿名内部类的使用,特别是在集合和流操作中,使代码更加简洁和易读。
2. Lambda表达式的语法
Lambda表达式的基本语法如下:
(parameters) -> expression
或
(parameters) -> { statements; }
具体语法形式包括:
- 无参数:
() -> System.out.println("Hello, World!"); - 一个参数,无需括号:
x -> x * x - 多个参数:
(x, y) -> x + y - 带有参数类型:
(int x, int y) -> x + y - 多行语句:
(x, y) -> { int sum = x + y; return sum; }
3. Lambda表达式的类型推断
Java编译器能够根据上下文推断Lambda表达式的参数类型,因此在大多数情况下,可以省略参数类型。例如:
Comparator<String> comparator = (a, b) -> a.compareToIgnoreCase(b);
在上面的例子中,编译器知道Comparator的类型参数是String,因此可以推断出a和b都是String类型。
二、使用Lambda表达式的场景
1. 替代匿名内部类
Lambda表达式最常见的用途之一是替代匿名内部类,使代码更加简洁。例如,在事件处理和线程创建中,可以使用Lambda表达式代替匿名内部类。
事件处理
Java 8之前的代码:
button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("Button clicked!");}
});
使用Lambda表达式:
button.addActionListener(e -> System.out.println("Button clicked!"));
线程创建
Java 8之前的代码:
new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Thread running");}
}).start();
使用Lambda表达式:
new Thread(() -> System.out.println("Thread running")).start();
2. 集合操作
Lambda表达式在集合操作中极为有用,特别是结合Java 8引入的Stream API,可以极大地简化代码并提高可读性。
过滤和映射
Java 8之前的代码:
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
List<String> filtered = new ArrayList<>();
for (String s : strings) {if (!s.isEmpty()) {filtered.add(s);}
}
使用Lambda表达式和Stream API:
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
List<String> filtered = strings.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
排序
Java 8之前的代码:
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() {@Overridepublic int compare(String a, String b) {return a.compareTo(b);}
});
使用Lambda表达式:
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
names.sort((a, b) -> a.compareTo(b));
3. 自定义函数式接口
除了使用已有的函数式接口,我们还可以自定义函数式接口,并使用Lambda表达式进行实现。
定义函数式接口
@FunctionalInterface
interface MyFunctionalInterface {void execute();
}
使用Lambda表达式实现接口
MyFunctionalInterface myFunction = () -> System.out.println("Executing...");
myFunction.execute();
三、Java 8中的其他相关特性
1. 内置函数式接口
Java 8引入了一些常用的函数式接口,位于java.util.function包中,包括:
Predicate<T>:接受一个参数,返回boolean。常用于条件判断。Function<T, R>:接受一个参数,返回一个结果。常用于转换操作。Consumer<T>:接受一个参数,无返回值。常用于执行操作。Supplier<T>:无参数,返回一个结果。常用于提供对象。BinaryOperator<T>:接受两个参数,返回一个结果。常用于二元运算。
示例
// Predicate
Predicate<String> isNotEmpty = s -> !s.isEmpty();
List<String> nonEmptyStrings = strings.stream().filter(isNotEmpty).collect(Collectors.toList());// Function
Function<String, Integer> toLength = String::length;
List<Integer> lengths = strings.stream().map(toLength).collect(Collectors.toList());// Consumer
Consumer<String> print = System.out::println;
strings.forEach(print);// Supplier
Supplier<String> stringSupplier = () -> "Hello";
String s = stringSupplier.get();// BinaryOperator
BinaryOperator<Integer> sum = Integer::sum;
int result = sum.apply(1, 2);
2. 方法引用
方法引用是一种更简洁的Lambda表达式写法,用于直接引用已有的方法。方法引用的语法有四种形式:
- 静态方法引用:
ClassName::staticMethod - 实例方法引用:
instance::instanceMethod - 特定类型的任意对象的方法引用:
ClassName::instanceMethod - 构造器引用:
ClassName::new
示例
// 静态方法引用
Function<String, Integer> parseInt = Integer::parseInt;// 实例方法引用
String str = "Hello";
Supplier<String> stringSupplier = str::toUpperCase;// 特定类型的任意对象的方法引用
Function<String, String> toUpperCase = String::toUpperCase;// 构造器引用
Supplier<List<String>> listSupplier = ArrayList::new;
四、Lambda表达式的优势和局限
1. 优势
- 简洁性:Lambda表达式大大简化了代码,使代码更加简洁和易读。
- 函数式编程:Lambda表达式支持函数式编程,使得Java能够更好地处理集合操作和并行流处理。
- 代码重用:通过使用Lambda表达式和方法引用,可以更容易地实现代码重用。
2. 局限
- 调试困难:由于Lambda表达式是匿名的,调试和排查问题可能比传统方法更困难。
- 学习曲线:对于没有函数式编程背景的开发者,理解和使用Lambda表达式可能需要一些时间。
- 性能开销:虽然Lambda表达式的性能一般较好,但在某些情况下,可能会引入额外的开销,如创建大量短命对象。
五、实战示例
以下是一个完整的示例,展示如何使用Lambda表达式和Stream API处理集合数据。
示例背景
假设我们有一个员工列表,我们需要进行以下操作:
- 过滤出年龄大于30的员工。
- 提取员工的名字。
- 对名字进行排序。
- 将名字转换为大写。
- 打印结果。
代码实现
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;class Employee {private String name;private int age;public Employee(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}@Overridepublic String toString() {return "Employee{name='" + name + "', age=" + age + '}';}
}public class LambdaExample {public static void main(String[] args) {List<Employee> employees = Arrays.asList(new Employee("John", 25),new Employee("Jane", 35),new Employee("Jack", 40),new Employee("Jill", 22));List<String> result = employees.stream().filter(e -> e.getAge() > 30).map(Employee::getName).sorted().map(String::toUpperCase).collect(Collectors.toList());result.forEach(System.out::println);}
}
输出结果
JACK
JANE
通过这个示例,我们可以看到Lambda表达式和Stream API如何简化集合数据的处理,并使代码更加简洁和易读。
Lambda表达式是Java 8引入的一个重要特性,极大地增强了Java的表达能力和简洁性。通过Lambda表达式,开发者可以更方便地编写函数式代码,简化集合操作,提升代码的可读性和可维护性。
结合Stream API和方法引用,Lambda表达式使得Java能够更好地应对现代编程需求。尽管Lambda表达式也有其局限性,但它在提升开发效率和代码质量方面的优势是显而易见的。掌握和熟练运用Lambda表达式,对于现代Java开发者来说是必不可少的技能。
黑马程序员免费预约咨询

相关文章:
如何理解 Java 8 引入的 Lambda 表达式及其使用场景
Lambda表达式是Java 8引入的一项重要特性,它使得编写简洁、可读和高效的代码成为可能。Lambda表达式本质上是一种匿名函数,能够更简洁地表示可传递的代码块,用于简化函数式编程的实现。 一、Lambda表达式概述 1. 什么是Lambda表达式 Lambd…...
GPT-4与GPT-4O的区别详解:面向小白用户
1. 模型介绍 在人工智能的语言模型领域,OpenAI的GPT-4和GPT-4O是最新的成员。这两个模型虽然来源于相同的基础技术,但在功能和应用上有着明显的区别。 GPT-4:这是一个通用型语言模型,可以理解和生成自然语言。无论是写作、对话还…...
使用throttle防止按钮多次点击
背景:如上图所示,点击按钮,防止按钮点击多次 <div class"footer"><el-button type"primary" click"submitThrottle">发起咨询 </el-button> </div>import { throttle } from loda…...
Echarts 在折线图的指定位置绘制一个图标展示
文章目录 需求分析需求 在线段交汇处用一个六边形图标展示 分析 可以使用 markPoint 和 symbol 属性来实现。这是一个更简单和更标准的方法来添加标记点在运行下述代码后,你将在浏览器中看到一个折线图,其中在 [3, 35] (即图表中第四个数据点 Thu 的 y 值为 35 的位置)处…...
适用于 Windows 的 8 大数据恢复软件
数据恢复软件可帮助您恢复因意外删除或由于某些技术故障(如硬盘损坏等)而丢失的数据。这些工具可帮助您从硬盘驱动器 (HDD) 中高效地恢复丢失的数据,因为这些工具不支持从 SSD 恢复数据。重要的是要了解,您删除的数据不会被系统永…...
HTTP基础
一、HTTP协议 1、HTTP协议概念 HTTP的全称是:Hyper Text Transfer Protocol,意为 超文本传输协议。它指的是服务器和客户端之间交互必须遵循的一问一答的规则。形容这个规则:问答机制、握手机制。 它规范了请求和响应内容的类型和格式, 是基于…...
深入了解Linux命令:visudo
深入了解Linux命令:visudo 在Linux系统中,sudo(superuser do)是一个允许用户以其他用户身份(通常是超级用户或其他用户)执行命令的程序。sudo的配置文件/etc/sudoers存储了哪些用户可以执行哪些命令的权限…...
十大排序 —— 希尔排序
十大排序 —— 希尔排序 什么是希尔排序插入排序希尔排序递归版本 我们今天来看另一个很有名的排序——希尔排序 什么是希尔排序 希尔排序(Shell Sort)是插入排序的一种更高效的改进版本,由Donald Shell于1959年提出。它通过比较相距一定间…...
SpringCloud Hystrix服务熔断实例总结
SpringCloud Hystrix断路器-服务熔断与降级和HystrixDashboard SpringCloud Hystrix服务降级实例总结 本文采用版本为Hoxton.SR1系列,SpringBoot为2.2.2.RELEASE <dependency><groupId>org.springframework.cloud</groupId><artifactId>s…...
为什么没有输出九九乘法表?
下面的程序本来想输出九九乘法表到屏幕上,为什么没有输出呢?怎样修改? <!DOCTYPE html> <html> <head> <meta charset"utf-8" /> <title>我的HTML练习</title> …...
EasyRecovery5步轻松恢复电脑手机数据,EasyRecovery带你探索!
在当今的数字化时代,数据已经成为我们生活和工作中不可或缺的一部分。无论是个人照片、工作文件还是重要的商业信息,数据的安全存储和恢复都显得尤为重要。EasyRecovery作为一款广受欢迎的数据恢复软件,为用户提供了强大的数据恢复功能&#…...
904. 水果成篮
904. 水果成篮 原题链接:完成情况:解题思路:参考代码:_904水果成篮_滑动窗口 错误经验吸取 原题链接: 904. 水果成篮 https://leetcode.cn/problems/fruit-into-baskets/description/ 完成情况: 解题思…...
在618集中上新,蕉下、VVC们为何押注拼多多?
编辑|Ray 自前两年崛起的防晒产品,今年依旧热度不减。 头部品牌蕉下,2020年入驻拼多多,如今年销售额已过亿元。而自去年起重点押注拼多多的时尚防晒品牌VVC,很快销量翻番。这两家公司,不约而同在618之前上…...
Maximo Attachments配置
以下内容以 Windows 上 Maximo 为例,并假定设置 DOCLINKS 的根路径为 “C:\DOCLINKS”。 HTTP Server配置 修改C:\Program Files\IBM\HTTPServer\conf\httpd.conf文件 查找 “DocumentRoot” 并修改成如下配置 DocumentRoot "C:\DOCLINKS"查找 “<…...
一分钟了解香港的场外期权报价
香港的场外期权报价 在香港这个国际金融中心,场外期权交易是金融市场不可或缺的一部分。场外期权,作为一种非标准化的金融衍生品,为投资者提供了在特定时间以约定价格买入或卖出某种资产的机会。对于希望参与这一市场的投资者来说࿰…...
专业开放式耳机什么牌子更好?六大技巧教你不踩坑!
相信很多入坑的朋友再最开始挑选耳机的时候都会矛盾,现在市面上这么多耳机,我该怎么选择?其实对于开放式耳机,大家都没有一个明确的概念,可能会为了音质的一小点提升而耗费大量的资金,毕竟这是一个无底洞。…...
注意!!24软考系统集成有变化,第三版考试一定要看这个!
系统集成在今年年初改版之后,上半年的考试也取消了,留给大家充足的时间来学习新的教材和考纲。但11月也将是第三版考纲的第1次考试,重点到底有什么?今天带大家详细的了解一下最新版中项考试大纲。 一、考试说明 1.考试目标 通过…...
Redis数据结构HyperLogLog以及布隆过滤器
HyperLogLog 引言 在开始之前,先思考一个常见的业务问题:如果负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的UV数据,然后来开发这个统计模块,需要如何实现? 如果统计PV非常好办&…...
C++——从C语言快速入门
目录 一、数组 1、声明数组 2、初始化数组 3、访问数组元素 4、示例 5、注意事项 6、数组小练习 计算器支持加减乘除 数组找最大值 二、指针 三、字符串 string 类型 一、数组 在 C 中,数组是一种存储固定大小的相同类型元素的序列。数组的所有元素都存…...
thinkpad T440p ubuntu-slam软件安装记录
安装问题 1.ubuntu20.04安装后提示"x86/cpu:VMX(outside TXT) disabled by BIOS" 这是虚拟化被禁止了,到BIOS里去把Virtualization选项打开即可。 2.ACPI Error:Needed type[Reference],found [Integer] 等错误 link这篇博客中提到该问题,…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
