探索Java Stream API:高效处理集合的利器

文章目录

    • 一、Stream API简介
      • 1.1 什么是Stream?
      • 1.2 Stream的特点
    • 二、Stream API的基本操作
      • 2.1 创建Stream
      • 2.2 中间操作
      • 2.3 终端操作
    • 三、Stream API的高级应用
      • 3.1 并行Stream
      • 3.2 复杂数据处理
      • 3.3 Stream与Optional
    • 四、最佳实践
      • 例子 1: 筛选和映射
      • 例子 2: 排序和收集
      • 例子 3: 分组和汇总
      • 例子 4: 并行流
    • 五、总结

在Java 8及之后的版本中,Stream API的引入无疑为Java的集合处理带来了革命性的变化。Stream API提供了一种高效、声明式的方式来处理数据集合(如List、Set等),使得数据处理代码更加简洁、易于理解和维护。本文将深入探讨Java Stream API的核心概念、常用操作、以及如何通过Stream实现复杂的数据处理逻辑。

在这里插入图片描述

一、Stream API简介

1.1 什么是Stream?

Stream(流)是Java 8中引入的一个关键抽象概念,它允许你以声明方式处理数据集合(包括数组)。Stream API通过对集合(Collection)的封装,提供了一种高级迭代器抽象。通过Stream,你可以利用Lambda表达式来执行复杂的集合操作,如筛选、排序、映射等,而无需修改原始数据源。

1.2 Stream的特点

非破坏性:Stream操作不会修改原始数据源。
惰性求值:Stream操作是延迟执行的,只有在需要结果时才会进行实际处理。
可消费性:Stream只能被消费一次,一旦遍历过,就不能再次遍历。
中间操作与终端操作:Stream操作分为中间操作和终端操作,中间操作返回Stream本身,可以链式调用;终端操作则返回一个结果或副作用,如集合、void等。

二、Stream API的基本操作

2.1 创建Stream

通过集合的.stream()或.parallelStream()方法创建。
通过Stream.of()、Stream.builder()或Stream.generate()等静态方法创建。
通过数组的Arrays.stream()方法创建。

2.2 中间操作

筛选(filter):通过Lambda表达式过滤元素。
映射(map):将每个元素映射(转换)成另一种形式。
排序(sorted):对流中的元素进行排序。
去重(distinct):去除流中的重复元素。
扁平化(flatMap):将流中的每个元素转换成流,然后将所有流连接成一个流。

2.3 终端操作

收集(collect):将流中的元素收集到新的集合中。
匹配(anyMatch、allMatch、noneMatch):检查流中的元素是否满足某种条件。
归约(reduce):将流中的元素反复结合起来,得到一个值。
查找(findFirst、findAny):查找流中的元素。
forEach:对流中的每个元素执行操作。

三、Stream API的高级应用

3.1 并行Stream

并行Stream利用多核处理器的优势,可以同时处理流中的多个元素,显著提高处理速度。通过集合的.parallelStream()方法可以获取并行Stream。但需要注意的是,并非所有情况下并行处理都能带来性能提升,合理的线程管理和数据分割是关键。

3.2 复杂数据处理

Stream API结合Lambda表达式和函数式接口,可以非常灵活地处理复杂的数据转换和聚合逻辑。例如,可以通过Collectors类提供的静态方法来实现复杂的收集操作,如分组(groupingBy)、分区(partitioningBy)、汇总(summingInt)等。

3.3 Stream与Optional

Optional是Java 8引入的另一个重要特性,用于避免空指针异常。Stream API在处理过程中经常会与Optional结合使用,以更优雅地处理可能为null的元素。

四、最佳实践

以下是一些使用Java Stream API的具体例子,这些例子将涵盖Stream的基本操作和一些更高级的用法。

例子 1: 筛选和映射

假设我们有一个Person类,包含姓名和年龄,我们想要从一组Person对象中筛选出年龄大于18岁的人,并将他们的名字收集到一个列表中。

/***  筛选和映射* @author senfel* @date 2024/8/15 17:49 * @return void*/
@Test
public void test(){List<Person> people = Arrays.asList(new Person("Alice", 30),new Person("Bob", 19),new Person("Charlie", 17),new Person("David", 22));List<String> adults = people.stream().filter(p -> p.age > 18).map(Person::getName).collect(Collectors.toList());// 输出: [Alice, Bob, David]System.out.println(adults); 
}@Data
class Person {String name;int age;Person(String name, int age) {this.name = name;this.age = age;}
}

例子 2: 排序和收集

现在,如果我们想要根据年龄对这些人进行排序,并将排序后的结果收集到一个新的列表中。

/*** 排序和收集* @author senfel* @date 2024/8/15 17:52 * @return void*/
@Test
public void test2(){List<Person> people = Arrays.asList(new Person("Alice", 30),new Person("Bob", 19),new Person("Charlie", 17),new Person("David", 22));List<Person> sortedPeople = people.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(Collectors.toList());for (Person p : sortedPeople) {//Charlie: 17//Bob: 19//David: 22//Alice: 30System.out.println(p.name + ": " + p.age);}
}
@Data
class Person {String name;int age;Person(String name, int age) {this.name = name;this.age = age;}
}

例子 3: 分组和汇总

假设我们想要根据年龄将人们分组,并计算每个年龄组中的人数。

/*** 分组和汇总* @author senfel* @date 2024/8/15 17:53 * @return void*/
@Test
public void test3(){List<Person> people = Arrays.asList(new Person("Alice", 30),new Person("Bob", 19),new Person("Charlie", 17),new Person("David", 22));Map<Integer, Long> ageCount = people.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));//Age 17: 1//Age 19: 1//Age 22: 1//Age 30: 1ageCount.forEach((age, count) -> System.out.println("Age " + age + ": " + count));
}@Data
class Person {String name;int age;Person(String name, int age) {this.name = name;this.age = age;}
}

例子 4: 并行流

现在,如果我们想要利用多核处理器来并行处理数据,以提高性能(特别是在处理大量数据时)。

/*** 并行流* @author senfel* @date 2024/8/15 17:54* @return void*/
@Test
public void test4(){List<Person> people = Arrays.asList(new Person("Alice", 30),new Person("Bob", 19),new Person("Charlie", 17),new Person("David", 22));long count = people.parallelStream().filter(p -> p.age > 18).count();//Number of adults: 3System.out.println("Number of adults: " + count);
}@Data
class Person {String name;int age;Person(String name, int age) {this.name = name;this.age = age;}
}

注意:并行流的使用需要谨慎,因为它可能不总是比串行流更快,特别是在处理小数据集或数据集已经被很好地分区时。此外,并行流中的操作可能不是线程安全的,因此确保流中的操作是线程安全的非常重要。

五、总结

Java Stream API以其简洁的语法和强大的功能,为Java集合处理带来了全新的体验。通过Stream API,我们可以以声明式的方式处理数据集合,使代码更加简洁、易于理解和维护。同时,结合Lambda表达式和函数式接口,Stream API还能轻松实现复杂的数据转换和聚合逻辑。然而,在使用Stream API时,我们也需要注意其生命周期、并行与串行的选择以及与其他Java特性的结合使用,以充分发挥其优势。

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

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

相关文章

什么是流批一体?怎样理解流批一体?

目录 一、流式处理与批量处理概述 1.流式处理 2.批量处理 3.流批一体的定义 二、流批一体的关键特点 三、流批一体的技术实现 四、应用场景 五、实施流批一体的考虑因素 流批一体听起来很简单&#xff0c;但内涵却十分复杂。它包含了计算语义、编程模型、API、调度、执行、shuf…

html+css+js网页制作 京东首页官网 ui还原度100%

htmlcssjs网页制作 京东首页官网 ui还原度100% 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 …

微服务系列:Spring Cloud 之 Feign、Ribbon、Hystrix 三者超时时间配置

Feign 自身有超时时间配置 Feign 默认集成的 Ribbon 中也有超时时间配置 假如我们又使用了 Hystrix 来实现熔断降级&#xff0c;Hystrix 自身也有一个超时时间配置 注: spring-cloud-starter-openfeign 低一点的版本中默认集成的有 Hystrix&#xff0c;高版本中又移除了。 …

x264 编码器 SSIM 算法源码分析

SSIM SSIM(Structural Similarity Index)是一种用于衡量两幅图像之间视觉相似度的指标。它不仅考虑了图像的亮度、对比度和饱和度,还考虑了图像的结构信息。SSIM的值介于-1到1之间,值越接近1表示两幅图像越相似。 SSIM是基于以下三个方面来计算的: 亮度(Luminance):比…

MLM之GPT-4o:在GPT-4o的806版本的 API 中引入结构化输出—可以可靠地遵循开发人员提供的 JSON 模式

MLM之GPT-4o&#xff1a;在GPT-4o的806版本的 API 中引入结构化输出—可以可靠地遵循开发人员提供的 JSON 模式 导读&#xff1a;2024年8月6日&#xff0c;OpenAI推出了新的API功能"结构化输出"&#xff0c;旨在更好地帮助人们理解和与大型语言模型的输出进行交互。这…

Linux系统编程(10)线程资源回收和互斥锁

一、pthread_cancel函数 pthread_cancel 函数用于请求取消一个线程。当调用 pthread_cancel 时&#xff0c;它会向指定的线程发送一个取消请求。 #include <pthread.h>int pthread_cancel(pthread_t thread);thread&#xff1a;要发送取消请求的线程标识符。 成功时&a…

Dify 开源大语言模型(LLM) 应用开发平台如何使用Docker部署与远程访问

目录 ⛳️推荐 前言 1. Docker部署Dify 2. 本地访问Dify 3. Ubuntu安装Cpolar 4. 配置公网地址 5. 远程访问 6. 固定Cpolar公网地址 7. 固定地址访问 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享…

Javascript反调试实现判断用户是否打开了浏览器控制台

前言 晓杰最近在研究如何防止用户恶意调试前端网页代码&#xff0c;防止打开控制台进行调试&#xff0c;首先禁用了浏览器页面右键事件和F12等快捷键&#xff01;然后利用了创建元素是否成功方式进行校验,具体实现代码如下。 代码 document.addEventListener(keydown, functi…

(贪心) LeetCode 376. 摆动序列

原题链接 一. 题目描述 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如&#xff0c; [1, 7, 4, 9, 2,…

【LeetCode每日一题】——623.在二叉树中增加一行

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 广度优先遍历 二【题目难度】 中等 三【题目编号】 623.在二叉树中增加一行 四【题目描述】…

【每日刷题】Day100

【每日刷题】Day100 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 【模板】堆_牛客题霸_牛客网 (nowcoder.com) 2. 【模板】链表_牛客题霸_牛客网 (nowcoder.com) 3…

红酒与旅游攻略:旅行途中的风味之选

在旅行的道路上&#xff0c;我们总是渴望寻找那些能够触动心灵、留下深刻记忆的不同体验。而红酒&#xff0c;作为一种充满韵味和故事的饮品&#xff0c;无疑是旅行途中的风味之选。洒派红酒&#xff08;Bold & Generous&#xff09;&#xff0c;这款定制红酒&#xff0c;以…

【公式推导】Elucidating the Design Space of Diffusion-Based Generative Models 【论文精读】

Elucidating the Design Space of Diffusion-Based Generative Models 论文精读 关注B站可以观看更多实战教学视频&#xff1a;hallo128的个人空间 【更新中】EDM论文精读 论文链接 &#xff08;1&#xff09;论文&#xff1a;Elucidating the Design Space of Diffusion-Base…

连接投影仪/显示器只能扩展不能复制的解决方案

原文章&#xff1a;https://iknow.lenovo.com.cn/detail/121481 故障现象&#xff1a; 笔记本外接投影仪/显示器后&#xff0c;笔记本屏幕有显示&#xff0c;但投影仪却只有背景或没有显示&#xff1b; 原因分析&#xff1a; 此现象多发生在双显卡机型上&#xff0c;笔记本屏…

旺店通·企业奇门对接打通旺店通·企业奇门库存查询接口与创建盘点单接口

旺店通企业奇门对接打通旺店通企业奇门库存查询接口与创建盘点单接口 接入系统&#xff1a;旺店通企业奇门 慧策&#xff08;原旺店通&#xff09;是一家技术驱动型智能零售服务商&#xff0c;基于云计算PaaS、SaaS模式&#xff0c;以一体化智能零售解决方案&#xff0c;帮助零…

Python爬虫与数据分析:中国大学排名的深度挖掘

前言 &#x1f449; 小编已经为大家准备好了完整的代码和完整的Python学习资料&#xff0c;朋友们如果需要可以扫描下方CSDN官方认证二维码或者点击链接免费领取【保证100%免费】 一、选题背景 高考作为中国学生生涯中最为重要的事&#xff0c;在高考之后&#xff0c;选择一所…

Vision Transformer学习笔记

论文链接&#xff1a;https://arxiv.org/abs/2010.11929 项目链接&#xff1a;https://github.com/google-research/vision_transformer 本文代码链接&#xff1a;https://gitcode.com/gh_mirrors/de/deep-learning-for-image-processing/tree/master/pytorch_classification/v…

大模型面试系列-大模型算法工程师的面试题目与解答技巧详细说明

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下大模型面试系列-大模型算法工程师的面试题目与解答技巧详细说明。 文章目录 大模型算法工程师面试题1. Llama 2 中使用的注意力机制是什么&#xff1f;描述一下查询分组注意力。2. LangChain 的结构详细描述一下。…

【go语言】go-webview2用法(持续更新)

文章目录 背景核心接口和方法扩展接口遗憾的是 背景 目前为止&#xff0c;已经有很多优秀的electron应用。但其特点也很明显&#xff1a;使用htmlcssjs构建的布局很精致&#xff0c;但是体积不容小觑&#xff08;最新版electron-egg打包出来的程序已经300MB&#xff09;。 vs…

014集——浮点数值类型——C#学习笔记

浮点类型的特征 C# 支持以下预定义浮点类型&#xff1a; double a 12.3; System.Double b 12.3; 每个浮点类型的默认值都为零&#xff0c;0。 每个浮点类型都有 MinValue 和 MaxValue 常量&#xff0c;提供该类型的最小值和最大有限值。 float and double 类型还提供可表示非…