Java中的Lambda表达式和Stream API详解

在现代Java开发中,Lambda表达式Stream API是简化代码、提高可读性和开发效率的关键工具。Java 8引入的这两大功能不仅增强了语言的表达力,还大幅提升了处理集合和数据流的能力。本文将详细解析Lambda表达式和Stream API的使用方法,并结合实际示例展示它们如何改变传统的编程方式。

1. 什么是Lambda表达式?

Lambda表达式是Java 8引入的一个重要特性,它使得可以用更简洁的语法来表达函数式接口(只有一个抽象方法的接口)的实例。Lambda表达式允许你把行为传递到某些方法中,例如集合的排序、过滤等操作,使代码更简洁和清晰。

1.1 Lambda表达式的语法

Lambda表达式的基本语法如下:

(parameters) -> expression
(parameters) -> { statements; }
  • 参数列表:可以有零个或多个参数,参数类型可以省略,编译器会通过上下文进行推断。
  • 箭头符号 ->:表示Lambda的主体开始。
  • Lambda主体:可以是一个简单的表达式,或者是用大括号括起来的代码块。

1.2 Lambda表达式的示例

示例1:使用Lambda表达式进行排序

传统的排序方式如下:

List<String> names = Arrays.asList("John", "Jane", "Doe", "Alice");
Collections.sort(names, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return s1.compareTo(s2);}
});

使用Lambda表达式,可以简化为:

List<String> names = Arrays.asList("John", "Jane", "Doe", "Alice");
names.sort((s1, s2) -> s1.compareTo(s2));

Lambda表达式使得代码更简洁和易读,省去了冗长的匿名内部类。

示例2:使用Lambda表达式遍历集合
List<String> names = Arrays.asList("John", "Jane", "Doe", "Alice");
names.forEach(name -> System.out.println(name));

forEach()方法接受一个Lambda表达式作为参数,可以对集合中的每个元素执行操作。

2. 什么是Stream API?

Stream API是Java 8引入的另一个重要特性,专门用于处理集合数据。Stream API 提供了声明式编程风格,可以对集合对象执行复杂的数据操作(如过滤、排序、映射、统计等),而无需编写繁琐的循环和条件判断代码。

2.1 什么是流(Stream)?

Stream代表着元素的序列,数据可以来自集合、数组、I/O通道等。流操作是惰性的,即只有在需要结果时才会执行。Stream API支持两种类型的操作:

  • 中间操作:返回一个新的流,支持链式调用,如filter()map()sorted()等。
  • 终端操作:产生结果或副作用,例如forEach()collect()reduce()等。

2.2 Stream API的工作流程

  1. 创建流:从集合、数组或生成器中创建流。
  2. 中间操作:对流中的元素进行转换或过滤,产生一个新的流。
  3. 终端操作:触发流的计算,生成结果或产生副作用。

2.3 Stream API示例

示例1:使用Stream进行过滤和排序

假设我们有一个包含多个字符串的列表,想要过滤出以“A”开头的名字,并按字母顺序排序:

List<String> names = Arrays.asList("John", "Jane", "Doe", "Alice", "Anna");List<String> result = names.stream().filter(name -> name.startsWith("A")).sorted().collect(Collectors.toList());System.out.println(result);  // 输出:[Alice, Anna]
  • stream():从列表创建一个流。
  • filter():过滤出以“A”开头的字符串。
  • sorted():对结果进行排序。
  • collect():将结果收集回列表。
示例2:使用Stream进行数据转换(map)

map()方法可以对流中的每个元素进行转换操作:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);List<Integer> squares = numbers.stream().map(n -> n * n)  // 每个数字的平方.collect(Collectors.toList());System.out.println(squares);  // 输出:[1, 4, 9, 16, 25]

这里,我们使用map()方法将数字列表中的每个元素平方,并返回一个新的列表。

3. Lambda表达式与Stream API的结合

Lambda表达式与Stream API结合后,可以大大简化代码,尤其是在处理集合时。以下是一个典型的例子:

示例:结合Lambda和Stream API

List<String> names = Arrays.asList("John", "Jane", "Doe", "Alice", "Anna");long count = names.stream().filter(name -> name.length() > 3)  // 筛选名字长度大于3的.count();  // 统计符合条件的元素个数System.out.println(count);  // 输出:3

在这段代码中,我们通过filter()和Lambda表达式筛选出名字长度大于3的元素,随后使用count()终端操作来计算数量。整个过程没有显式的循环和条件判断,代码简洁清晰。

4. 常见的Stream API操作

4.1 filter():过滤流中的元素

filter()方法用于根据条件过滤流中的元素:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);numbers.stream().filter(n -> n % 2 == 0)  // 筛选偶数.forEach(System.out::println);  // 输出:2, 4, 6

4.2 map():映射每个元素

map()将流中的元素转换为另一种形式:

List<String> names = Arrays.asList("John", "Jane", "Doe");names.stream().map(String::toUpperCase)  // 转换为大写.forEach(System.out::println);  // 输出:JOHN, JANE, DOE

4.3 collect():收集流的结果

collect()方法是终端操作,用于将流中的元素收集到集合、数组等容器中:

List<String> filteredNames = names.stream().filter(name -> name.startsWith("J")).collect(Collectors.toList());System.out.println(filteredNames);  // 输出:[John, Jane]

4.4 reduce():将流中的元素合并为一个结果

reduce()方法用于将流中的元素进行聚合计算:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);int sum = numbers.stream().reduce(0, Integer::sum);  // 求和System.out.println(sum);  // 输出:15

5. Lambda与Stream API的优势

5.1 简洁性

Lambda表达式和Stream API的最大优势在于代码的简洁性。通过声明式编程方式,避免了传统Java代码中常见的循环和条件判断,使得代码更具表达力。

5.2 可读性

使用Stream API后,代码意图更加明确。例如,通过filter()map()等链式操作,代码逻辑一目了然,读者可以轻松理解每一步的操作。

5.3 性能优化

Stream API还支持并行流(Parallel Stream),可以充分利用多核处理器的优势。在大数据集上,可以通过parallelStream()轻松实现并行处理,提升性能:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);int sum = numbers.parallelStream().reduce(0, Integer::sum);System.out.println(sum);  // 输出:55

并行流会自动将流中的任务分解到多个线程中执行。

6. 总结

Java中的Lambda表达式和Stream API为开发者提供了简洁而强大的工具,用于处理集合和数据流。Lambda表达式让Java具备了函数式编程的能力,而Stream API则提供了强大的数据处理管道。结合这两者,开发者能够用更少的代码实现复杂的数据操作,提高代码的可读性和性能。

通过学习和使用这些特性,Java开发者不仅可以编写更简洁优雅的代码,还能更好地利用现代硬件的多核优势进行并行计算。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/53955.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FreeRTOS常用API接口函数

提示&#xff1a;FreeRTOS常用API接口函数&#xff1a;并对部分参数附上自己的解释,后面继续补充 FreeRTOS常用API接口函数 1.任务相关的API1.1 创建任务&#xff1a;xTaskCreate1.2 开启任务调度器函数&#xff1a;vTaskStartScheduler1.3 任务的删除&#xff1a;vTaskDelete1…

Android Service服务使用方法

启动服务的方法 我们要隐式启动一个Service&#xff0c;首先我们需要配置AndroidMainfest.xml <service android:name".MyAsdlService"><intent-filter><action android:name"com.example.myasdlservice" /></intent-filter><…

Rollup 插件机制深入学习

插件系统的核心 Rollup 的插件系统是其强大功能的一部分&#xff0c;能够让开发者通过插件定制打包过程。插件的核心包括&#xff1a; Graph&#xff1a;Rollup 的全局图形表示&#xff0c;用于管理入口点及其依赖关系。PluginDriver&#xff1a;插件驱动器&#xff0c;负责调…

【ArcGISProSDK】初识

ArcGIS Pro SDK 提供四种主要的可扩展性模式&#xff1a;加载项、托管配置、插件数据源和 CoreHost 应用程序。 各模块文件对比 API 核心 核心程序集位于 {ArcGIS Pro 安装文件夹}\bin 中。 程序集描述ArcGIS.Core.dll 提供 CIM、地理数据库、几何图形和公共设施网络 API。 …

Prometheus+grafana监控spring boot 3运行情况

使用Prometheus和Grafana来监控Spring Boot 3应用的运行情况是一种强大的监控策略&#xff0c;可以帮助你了解应用的性能、健康状况以及潜在的问题。以下是如何配置这种监控系统的基本步骤&#xff1a; 1. Spring Boot 应用配置 首先&#xff0c;确保你的Spring Boot 3应用已…

Notepad++插件:TextFX 去除重复行

目录 一、下载插件 TextFX Characters 二、去重实操 2.1 选中需要去重的文本 2.2 操作插件 2.3 结果展示 2.3.1 点击 Sort lines case sensitive (at column) 2.3.2 点击 Sort lines case insensitive (at column) 一、下载插件 TextFX Characters 点【插件】-【插件管理…

从头开始学MyBatis—02基于xml和注解分别实现的增删改查

首先介绍此次使用的数据库结构&#xff0c;然后引出注意事项。 通过基于xml和基于注解的方式分别实现了增删改查&#xff0c;还有获取参数值、返回值的不同类型对比&#xff0c;帮助大家一次性掌握两种代码编写能力。 目录 数据库 数据库表 实体类 对应的实体类如下&#x…

JS 扩展运算符有哪些使用场景?

你好&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 扩展运算符有哪些使用场景&#xff1f;直接进入正题 一、复制数组 const a1 [1, 2];// 写法一 const a2 [...a1]; // 写法二 const [...a2] a1;二、合并数组 const part1 [1, 2, 3]; const part2 …

golang学习笔记16——golang部署与运维全攻略

推荐学习文档 golang应用级os框架&#xff0c;欢迎star基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总golang学习笔记01——基本数据类型golang学习笔记02——gin框架及基本原理golang学习笔记03——gin框架的核心数据结构golang学…

【C++基础概念理解——类的继承和嵌套】

基本概念 在 C 中&#xff0c;类的继承和嵌套类的定义是两种不同的概念。 class InitialSetupProcedure : public StateMachine //类的继承(符号是":")class InitialSetupProcedure::StateMachine //类的嵌套(符号是"::"&#xff0c;意思是类StateMach…

深度学习和计算机视觉:实现图像分类

深度学习在计算机视觉领域的应用已经取得了革命性的进展。从图像分类到对象检测&#xff0c;再到图像分割和生成&#xff0c;深度学习模型在这些任务中都展现出了卓越的性能。本篇文章将介绍如何使用深度学习进行图像分类&#xff0c;这是计算机视觉中的一个基础任务。 计算机…

什么是幂等

什么是幂等&#xff1f; 幂等简单来说就是“重复做同一件事&#xff0c;结果还是一样的”。比如&#xff0c;你按电视遥控器的开关按钮&#xff0c;按一次电视开了&#xff0c;再按一次电视关了。这个操作不是幂等的&#xff0c;因为你每按一次&#xff0c;结果都不一样。 再…

KTM580030bit 绝对角度细分器支持最多 4096 对极与一键非线性自校准集成双 16bit 2M SAR ADC

KTM5800 是一款 30bit 绝对角度细分 4096 对极编码细分器&#xff0c;可以与磁电阻传感器&#xff08; AM R/TMR &#xff09;搭配&#xff0c;构成一个高速高精度的非接触磁性编码器模块。它具有以非常高的采样速率 读取传感器上的差分模拟正弦和余弦信号的能力&#xf…

pytest 生成allure测试报告

allure的安装 github地址 allure资产列表 windows下载.zip&#xff0c;解压并配置环境变量PATH&#xff1b;linux下载安装allure&#xff0c;可以使用windows下解压的.zip文件&#xff08;通用&#xff09;&#xff0c;或者下载.rpm/.deb 文件进行安装并配置PATH&#xff1b;…

通信工程学习:什么是MRF多媒体资源功能、MRFC多媒体资源功能控制、MRFP多媒体资源功能处理

一、MRF多媒体资源功能 MRF&#xff08;Multimedia Resource Function&#xff0c;多媒体资源功能&#xff09;是3G/IMS网络中定义的提供多媒体资源功能的网络实体&#xff0c;它为3G/IMS网络的业务和承载提供媒体能力支持。MRF通过提供丰富的媒体处理功能&#xff0c;如播放声…

分块总结:时髦之裤

说白了就是南外分块题做的差不多了&#xff0c;来写一篇总结。 简要题意&#xff1a; 给一序列 a&#xff0c;初始时 a i i a_ii ai​i&#xff0c;有如下两个操作&#xff1a; 1.将[l,r]每个数改为x&#xff0c;该点增加贡献 ∣ a i − x ∣ |a_i-x| ∣ai​−x∣. 2.询问[l…

SQLite的入门级项目学习记录(二)

再补充一些基础知识&#xff1a; 并行操作的问题 1、可以多游标同时运行 SQLite&#xff0c;对于同一个连接sqlite3.connect(db_file)&#xff0c;可以同时创建多个游标&#xff0c;每个游标都是独立的&#xff0c;可以执行各自的SQL命令序列。 import sqlite3# 创建数据库连…

FAT32文件系统详细分析 (格式化SD nandSD卡)

FAT32 文件系统详细分析 (格式化 SD nand/SD 卡) 目录 FAT32 文件系统详细分析 (格式化 SD nand/SD 卡)1. 前言2.格式化 SD nand/SD 卡3.FAT32 文件系统分析3.1 保留区分析3.1.1 BPB(BIOS Parameter Block) 及 BS 区分析3.1.2 FSInfo 结构扇区分析3.1.3 引导扇区剩余扇区3.1.4 …

vue在一个组件引用其他组件

在vue一个组件中引用另一个组件的步骤 必须在script中导入要引用的组件需要在export default的components引用导入的组件(这一步经常忘记)在template使用导入的组件<script><!-- 第一步,导入--> import Vue01 from "@/components/Vue01.vue";

828华为云征文 | Flexus X 实例服务器网络性能深度评测

引言 随着互联网应用的快速发展&#xff0c;网络带宽和性能对云服务器的表现至关重要。在不同的云服务平台上&#xff0c;即便配置相同的带宽&#xff0c;实际的网络表现也可能有所差异。因此&#xff0c;了解并测试服务器的网络性能变得尤为重要。本文将以华为云X实例服务器为…