Java8 Stream 处理集合数据

别再只用map了!Java 8 Stream flatMap实战:从嵌套集合到文件处理,5个场景搞定数据扁平化 本文深入探讨Java 8 Stream flatMap的实战应用,通过5个典型场景展示如何高效处理嵌套集合、二维数组、Optional解包、文件处理和电商订单分析。flatMap作为数据扁平化的利器,能显著提升代码简洁性和性能,是替代传统循环的优选方案。 阅读详情

今天给大家带来 Java 8 Stream 讲解,为什么直接讲这个,是因为只要你学完,立刻就能上手,并能让它在你的代码中大展身手。

值得注意的是:学习 Stream 之前必须先学习 lambda 的相关知识。本文也假设读者已经掌握 lambda 的相关知识

本篇文章主要内容:

  • 介绍 Stream 以及 Stream 是如何处理集合的
  • 介绍 Stream 与集合的关系与区别
  • Stream 的基本方法介绍

一. 什么是 Stream

Stream 中文称为 “流”,通过将集合转换为这么一种叫做 “流” 的元素序列,通过声明性方式,能够对集合中的每个元素进行一系列并行或串行的流水线操作。换句话说,你只需要告诉流你的要求和条件,流就会自行根据要求和条件对元素进行快速处理,从而得到你想要的结果

二. 流操作

其中数据源便是原始集合,然后将如 List<T> 的集合转换为 Stream<T> 类型的流,并对流进行一系列的中间操作,比如过滤保留部分元素、对元素进行排序、类型转换等;最后再进行一个终端操作,可以把 Stream 转换回集合类型,也可以直接对其中的各个元素进行处理,比如打印、比如计算总数、计算最大值等等

很重要的一点是,很多流操作本身就会返回一个流,所以多个操作可以直接连接起来,我们来看看一条 Stream 操作的代码:

四. 实战

首先创建一个 Student 对象

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Student implements Serializable {

    /**
     * 学成名字
     */
    private String name;

    /**
     * 性别
     */
    private String sex;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 成绩分数
     */
    private Integer grade;

    /**
     * 学科
     */
    private String subject;
}

并且设置相应的值和集合数据

 List<Student> studentList = new ArrayList<Student>(16) {{
            add(new Student("张三", "男", 18, 85.5, "数学"));
            add(new Student("李四", "男", 16, 92.5, "语文"));
            add(new Student("张珊", "女", 16, 89.0, "英语"));
            add(new Student("小明", "男", 15, 65.5, "数学"));
            add(new Student("小红", "女", 17, 74.5, "语文"));
 }};

1. stream() / parallelStream()

最常用到的方法,将集合转换为流

Stream<Student> studentListStream = studentList.stream();

而 parallelStream() 是并行流方法,能够让数据集执行并行操作

Stream<Student> studentListParallelStream = studentList.parallelStream();

2. filter()

保留 boolean 为 true 的元素

 // 过滤保留年龄大于17的学生
List<Student> students = studentList.stream().filter(s -> 17 < s.getAge()).collect(Collectors.toList());

打印输出:[Student(name=张三, sex=男, age=18, grade=85.5, subject=数学)]

3. distinct()

去除重复元素,这个方法是通过类的 equals 方法来判断两个元素是否相等的

 // 过滤保留年龄大于17岁,去除相同名字的学生
List<String> students = studentList.stream().filter(s -> 17 == s.getAge()).map(Student::getName).distinct().collect(Collectors.toList());

打印输出: [小红]

4. sorted()

如果流中的元素的类实现了 Comparable 接口,即有自己的排序规则,那么可以直接调用 sorted() 方法对元素进行排序,需要自定义调用 sorted((T1, T2) -> return int) 实现 Comparator 接口

调用sorted()

// 年龄自然排序正序
List<Integer> students = studentList.stream().map(Student::getAge).sorted().collect(Collectors.toList());

打印输出:[15, 16, 16, 17, 17, 18]

调用sorted((T1, T2) -> return int)

// 年龄自然排序正序
List<Student> students = studentList.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());

// 或者:
List<Student> students = studentList.stream().sorted((t1, t2)-> t1.getAge() - t2.getAge()).collect(Collectors.toList());

打印输出:[Student(name=小明, sex=男, age=15, grade=65.5, subject=数学), Student(name=李四, sex=男, age=16, grade=92.5, subject=语文), Student(name=张珊, sex=女, age=16, grade=89.0, subject=英语), Student(name=小红, sex=女, age=17, grade=74.5, subject=语文), Student(name=小红, sex=女, age=17, grade=71.5, subject=英语), Student(name=张三, sex=男, age=18, grade=85.5, subject=数学)]

5. limit()

截取返回前 n 个元素

// 截取返回前 2 个学生
List<Student> students = studentList.stream().limit(2).collect(Collectors.toList());

打印输出:[Student(name=张三, sex=男, age=18, grade=85.5, subject=数学), Student(name=李四, sex=男, age=16, grade=92.5, subject=语文)]

6. skip()

去除(跳过)前 n 个元素

List<Student> students = studentList.stream().skip(4).collect(Collectors.toList());

打印输出: [Student(name=小红, sex=女, age=17, grade=74.5, subject=语文), Student(name=小红, sex=女, age=17, grade=71.5, subject=英语)]

注意事项:

  • skip(m)用在 limit(n) 前面时,先去除前 m 个元素再返回剩余元素的前 n 个元素
  • limit(n) 用在 skip(m) 前面时,先返回前 n 个元素再在剩余的 n 个元素中去除 m 个元素
List<Student> students = studentList.stream().skip(2).limit(1).collect(Collectors.toList());

List<Student> students = studentList.stream().limit(2).skip(1).collect(Collectors.toList());

打印输出1: [Student(name=张珊, sex=女, age=16, grade=89.0, subject=英语)]
打印输出2: [Student(name=李四, sex=男, age=16, grade=92.5, subject=语文)]

7. map()

将流中的每一个元素 T 映射为 R(类似类型转换, 可以转换为任意类型)

// 输出人名
List<String> students = studentList.stream().map(Student::getName).collect(Collectors.toList());

// 将所有人的分数加5分
List<Double> students = studentList.stream().map(s -> s.getGrade() + 5.0D).collect(Collectors.toList());

打印输出1:[张三, 李四, 张珊, 小明, 小红, 小红]
打印输出2:[90.5, 97.5, 94.0, 70.5, 79.5, 76.5]

newlist 里面的元素为 list 中每一个 Person 对象的 name 变量

8. flatMap()

将流中的每一个元素 T 映射为一个流,再把每一个流连接成为一个流

List<String> students = studentList.stream().map(s-> s.getName().split("")).flatMap(Arrays::stream).collect(Collectors.toList());

打印输出:[张, 三, 李, 四, 张, 珊, 小, 明, 小, 红, 小, 红]

上面例子中,我们的目的是把 studentList 中每个人名字符串元素以" "分割开,变成一个新的 List<String>。
首先 map 方法分割每个字符串元素,但此时流的类型为 Stream<String[ ]>,因为 split 方法返回的是 String[ ] 类型;所以我们需要使用 flatMap 方法,先使用Arrays::stream将每个 String[ ] 元素变成一个 Stream<String> 流,然后 flatMap 会将每一个流连接成为一个流,最终返回我们需要的 Stream<String>

9. anyMatch()

流中是否有一个元素匹配给定的 T -> boolean 条件

// 是否存在一个student对象的年龄等于18:
boolean b = studentList.stream().anyMatch(s -> 18 == s.getAge());
打印输出:true

10. allMatch()

流中是否所有元素都匹配给定的 T -> boolean 条件

boolean b = studentList.stream().allMatch(s -> 18 == s.getAge());

打印输出: false

11. noneMatch()

流中是否没有元素匹配给定的 T -> boolean 条件

boolean b = studentList.stream().noneMatch(s -> 18 == s.getAge());

打印输出:false

12. findAny() 和 findFirst()

  • findAny():找到其中一个元素 (使用 stream() 时找到的是第一个元素;使用 parallelStream() 并行时找到的是其中一个元素)
  • findFirst():找到第一个元素
Student student = studentList.stream().findFirst().get();
打印输出:Student(name=张三, sex=男, age=18, grade=85.5, subject=数学)

Student student = studentList.stream().findAny().get();
打印输出:Student(name=张三, sex=男, age=18, grade=85.5, subject=数学)

值得注意的是,这两个方法返回的是一个 Optional<T> 对象,它是一个容器类,能代表一个值存在或不存在,这个后面会讲到

14. reduce() 和 reduce()

用于组合流中的元素,如求和,求积,求最大值等

// 计算年龄总和:
Integer ages = studentList.stream().map(Student::getAge).reduce(Integer::sum).get();

// 或者:
Integer ages = studentList.stream().map(Student::getAge).reduce(0, Integer::sum);

其中,reduce 第一个参数 0 代表起始值为 0,lambda (a, b) -> a + b 即将两值相加产生一个新值:

// 计算年龄总乘积:
Integer ages = studentList.stream().map(Student::getAge).reduce(0, (t1, t2) -> t1 * t2);

15. count()

返回流中元素个数,结果为 long 类型

long count = studentList.stream().map(Student::getAge).count();

16. collect()

收集方法,我们很常用的是 collect(toList()),当然还有 collect(toSet()) 等,参数是一个收集器接口,这个后面会另外讲

List<Student> students = studentList.stream().unordered().collect(Collectors.toList());

17. forEach()

返回结果为 void,很明显我们可以通过它来干什么了,比方说:


// unordered() 还有这个比较不起眼的方法,返回一个等效的无序流,当然如果流本身就是无序的话,那可能就会直接返回其本身

// 打印各个元素:
studentList.forEach(System.out::println);

再比如说 MyBatis 里面访问数据库的 mapper 方法:

// 向数据库插入新元素:
studentList.stream().forEach(StudentMapper::insert);

 

 

 

 

电子技术——共栅和共源共栅放大器的高频响应 我们在之前学过无论是是CS放大器还是CE放大器,都可以看做是一个带通(IC低通)滤波器。在高频处的响应收到输入电容 $C_{in}$ 的限制(主要是米勒效应)。因此,若想扩大放大器的带宽,我们必须减小米勒效应,一种方案就是共栅放大器。 阅读详情

相关推荐

网络攻防实验——网络监听

利用CAIN实现ARP监听。

Trieyes_of_feng的博客 3193

【Java 8 新特性】Java Stream通过findAny()返回任意一条数据

Stream的findAny方法选择该流中的任何元素。 findAny方法的行为是不确定的,它可以自由选择流中的任何元素。 findAny方法有助于在并行操作中获得最大的性能,但它不能保证每次调用都得到相同的结果。 在java doc中的findAny()方法声明 Optional<T> findAny() 上述方法返回java.util.Optional,一个容器对象,可能包含也可能不包含非空值。 当方法在流中选择null值时,findAny抛出NullPointerException。

猫巳的博客 5万+

解决linux 2.5G网卡驱动问题

解决linux 2.5G网卡驱动问题 关键词:2.5G网卡驱动,ubuntu,安装,2.5G Ethernet LINUX driver,Realtek网卡驱动 由于2.5G网卡较新,各linux发行版的通用驱动已不适用,新装的系统会出现无法上网问题,由于国内网络环境去Realtek官网很难下载到驱动文件,故本文提供github上的2.5G Ethernet LINUX driver r8125 for kernel up to 5.6的版本驱动文件r8125-9.003.05.tar.bz2各位可以自

poorguy_aos的博客 1万+

Stream.findAny

Optional<T>findAny() 其作用就是从Stream中取任意一个元素,正常情况下一般会取第一个元素,在并行流的情况下会随机取一个元素。 下面看一个例子: void stream_findAny() { List<String> list = Arrays.asList("a","b","c","d","e","f","g"); Optional<String> opt = list.stream().findAn...

7455

Robosuite实战:通过Xbox手柄实现机械臂6-DoF精准控制的完整指南

本文详细介绍了如何通过Xbox手柄实现机械臂的6-DoF精准控制,结合Robosuite仿真环境与MuJoCo物理引擎,提供从环境配置到代码实现的完整指南。文章重点解析了手柄映射原理、核心控制代码以及数据采集优化技巧,帮助开发者高效完成机械臂控制任务。

weixin_29169505的博客 419

C#里使用NModbus来创建一个TCP从站服务

摘要:本文介绍了一个用C#实现的Modbus TCP从站服务器,基于.NET Framework 4.6.1开发。代码使用NModbus库创建TcpListener和ModbusSlaveNetwork,支持设置IP地址、端口号和从站ID。服务器实现了数据存储初始化功能(包括线圈和保持寄存器),并提供了启动/停止操作的UI界面和日志记录功能。该解决方案适用于需要调试Modbus TCP协议的场景,特别适合无法升级到更高版本.NET Framework的环境。

大坡3D软件开发 477

findAny()详解

Java8 的Stream语法可以说是声明式bai的代码了,所du以正如名字所说,是找到任何一个就行zhi 比如:有一个Integer的集dao合[1, 3, 5, 7] e.g 1 List<Integer> list = Arrays.asList(1, 3, 5, 7); Optional<Integer> any = list.stream().findAny(); 这样出来的话,这个any肯定就是1了,因为此时stream是有顺序的,相当于一个list,把list中的数字按

mingyuli的博客 2万+

【ACP】2025-最新-疑难题解析-1

即用户手动释放时,因实例释放保护开启,不会释放该 ECS 实例(不同云厂商具体实现有差异,但题目场景下选 C )。结合题目中标记,答案为。综上,答案选 B。综上,答案选 C。综上,答案选 D。综上,答案选 A。综上,答案选 A。综上,答案选 C。综上,答案选 D。综上,答案选 A。

jundao1997的专栏 362

java stream findany_Java 8 Stream findFirst() 与 findAny()

简介最近,写法采用Java 8 Stream API引入两种经常被误解的方法:findAny()和findFirst()。再次这两种方法之间的区别以及何时使用他进行做个笔记,使用Stream.findAny()findAny()方法允许您从Stream中找到任何元素,在寻找元素而无需注意相遇顺序是使用他。该方法返回一个Optional实例,如果Stream为空,则改实例为空。@Testpublic...

weixin_31068491的博客 1964

【产品经理修炼之道】-如何搭建企业级账务系统?

笔者公司的业务模式具有一定的独特性,不同于我们常见的市面上供应链类公司的进销存模式。公司主要为各大银行和金融机构提供信贷领域的风控服务,客户主要通过请求公司的数据产品接口产生费用,可以简单地理解为请求一次接口收费0.5元,一个月若是有1w人请求同一个接口则公司需要收费5000元。

xiaoli8748的专栏 5404

制作INCA和CANape通用的A2L

CANape和INCA通用的A2L配置与修改

赞的博客 5960

【java8】中stream的.findAny().orElse (null) 是什么意思?

举例: List<User> userList = new ArrayList(); User user1 = userList.stream().filter(user -> "zhangsan".equals(user.getUserName())).findAny().orElse(null); 1、filter为过滤,user代表userList中的一个User; 2、userList.stream().filter(user -> “zhangsan”.equals(us

ABCAA1024的博客 2万+

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

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

amy_mhd的博客 314

Java 8 Stream API处理集合数据

API 添加了一个新的抽象称为Stream(流),以一种声明的方式处理数据新建一个DTO用于测试main方法执行验证。

m0_37845840的博客 593

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

java8之stream:处理集合数据

Streams lambda表达式允许我们在不创建新类的情况下传递行为,从而帮助我们写出干净简洁的代码。lambda表达式是一种简单的语法结构,它通过使用函数式接口来帮助开发者简单明了的传递意图。 Stream是java8引入的一个重度使用lambda表达式的API。Stream使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的高...

琦彦 2万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Java 8 Stream API 完全指南:优雅处理集合数据

摘要:Java 8的Stream API为集合处理带来了革命性变革,提供声明式的函数式编程方式。文章系统介绍了Stream的核心概念、7种创建方式、中间操作(如filter、map)和终端操作(如collect、reduce),并详解并行流优化技巧。通过电商数据分析等实战案例,展示了Stream在复杂数据处理中的优势,包括代码简洁性、并行处理能力和惰性求值特性。最后给出性能优化建议,并对比传统循环,强调Stream适用于构建数据管道而非完全替代循环。

weixin_62938484的博客 1687

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

使用 Stream 处理集合数据【Java 1.8 新特性】

Stream是Java 8中引入的一个重要概念,它提供了对集合对象进行一系列操作的新方式,包括筛选、转换、聚合等。Stream API以声明式方式提供了对数据集合的高效操作,并且可以并行处理数据

qq_35215728的博客 830

Java8Stream(高效处理集合数据)

java8stream是处理数据集合,遍历数据集的高级迭代器,有助于提高我们写代码的效率!

小谷同学的博客 1516

【Java8】超神的Stream,高效处理数据集合

Java8给我们推出了很多新的语法,它允许以声明性方式处理数据集合。正是由于Sream的出现,让我们,我们可以通过简洁的代码,告别了以往使用for循环处理数据集合的历史。 使用Stream两部曲 把集合转换为stream 操作stream流,stream流在管道中经过中间操作符的处理,最后由最终操作符得到一系列处理的结果 中间操作符 流方法 含义 filter 过滤出元素 distinct 返回一个无重复元素的流 limit 返回一个不限定长度的流 skip 截取索引为n.

weixin_38207472的博客 616

《Java 8 Stream流:高效处理集合数据的利器》

在Java 8中,Stream API的引入为集合数据处理带来了革命性的变化。本博客将深入探讨Java 8 Stream流的优势、基本操作以及如何利用它来高效处理集合数据。我们将从Stream的基本概念开始,逐步介绍如何使用Stream进行过滤、映射、排序、聚合等操作。此外,还将探讨并行Stream的使用,以及如何优化Stream的性能。通过学习本博客,您将能够掌握Java 8 Stream流的核心技巧,提高数据处理效率,为您的Java编程技能锦上添花。

2301_81724645的博客 790

Java 8 Stream API:高效处理集合数据

Java 8引入了Stream API,它是一种用于高效处理集合数据的工具。Stream API提供了一种声明式的编程方式,可以让你更轻松地对集合进行过滤、映射、排序等操作。本教程将介绍Java Stream API的基本概念、用法以及在实际开发中的应用。

qq_38766930的博客 408

Java 8 Stream 与集合互转:高效处理集合数据的实战技巧

Stream与集合互转是Java开发常见操作,但存在多个易错点:1. Stream一次性消费特性导致重复使用时数据丢失;2. 集合特性差异(如List转Set自动去重)引发数据异常;3. 并行Stream转非线程安全集合造成数据丢失;4. 频繁互转导致性能下降;5. Java16+的Stream.toList()返回不可变集合可能引发异常。最佳实践包括:链式操作避免拆分Stream、明确目标集合特性、谨慎使用并行Stream、处理Map时注意key冲突。生产环境中应避免将Stream作为返回值,优先使用co

m0_67391377的博客 934

java8之stream:处理集合数据 lambda

https://blog.csdn.net/fly910905/article/details/70224131 Streams lambda表达式允许我们在不创建新类的情况下传递行为,从而帮助我们写出干净简洁的代码。lambda表达式是一种简单的语法结构,它通过使用函数式接口来帮助开发者简单明了的传递意图。 Stream是java8引入的一个重度使用lambda表达式的API。Stream使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达...

az44yao的专栏 386

Java8 - Stream API 处理集合数据

Java 8的Stream API提供了一种功能强大的方式来处理集合数据,以函数式和声明式的方式进行操作。Stream API允许您对元素集合执行操作,如过滤、映射和归约,以简洁高效的方式进行处理。下面是Java 8 Stream API的一些关键特性和概念:① 创建流:您可以从各数据源创建流,如集合、数组或I/O通道。② 中间操作:Stream提供了一组中间操作,可以链接在一起对数据进行转换或过滤。

你今天真好看呀 1514

Java8 Stream API在集合上执行复杂的数据处理查询

Java 8 引入的 Stream API 是一个高级工具,用于在集合上执行复杂的数据处理查询。Stream API 通过提供一系列的中间操作和最终操作,支持声明式处理(类似于SQL声明式语句)并且可以轻松使用多核架构

lin1151211427的博客 475

Java 8 Stream 流式编程:告别循环,优雅处理集合数据

Stream 配合 Lambda 重构集合业务代码,大幅减少模板代码,逻辑一目了然。Java 8 推出的 Stream 流式 API,基于 Lambda 表达式,采用链式调用,一行代码就能完成复杂集合运算,代码简洁易维护,同时支持并行流提升大数据处理效率。日常开发中,我们经常需要对 List、Map 做遍历、过滤、转换、求和、分组等操作。Stream 只能消费一次,执行终端操作后流关闭,不可重复使用;中间操作:过滤、映射、排序(延迟执行,不产生新集合)终端操作:收集、统计、遍历(触发执行,关闭流)

2401_88847177的博客 196
上一篇: Java8 集合Map/list排序
下一篇: Centos7的python2.7和yum完全卸载及重装
shareloke
博客等级 码龄10年 4741粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值