Java中的Stream

server/2024/12/16 18:32:18/

1. 什么是 Stream?

Stream 是 Java 8 引入的一种新方式,目的是帮助我们更简洁、更高效地处理集合(如 List、Set、Map 等)。你可以把 Stream 想象成一条“流水线”,数据就像是流水线上的原材料,经过流水线的各个环节处理,最后你会得到想要的结果。

2. 为什么要使用 Stream?

在没有 Stream 之前,处理集合数据时,我们通常会使用 循环 来逐个操作每个元素,这样代码冗长、难以维护。

传统做法:

假设我们有一个 List 存储了多个整数,我们想找出所有大于 10 的数字。
 

java">List<Integer> numbers = Arrays.asList(5, 12, 15, 8, 22);
List<Integer> result = new ArrayList<>();for (int num : numbers) {if (num > 10) {result.add(num);}
}
System.out.println(result);  // 输出 [12, 15, 22]

这种方式看起来没问题,但是如果我们需要对多个集合执行各种复杂的操作(过滤、排序、映射等),代码就会变得非常冗长。

使用 Stream:

Stream 让你可以通过一系列简单的“流式操作”来处理数据。
 

java">List<Integer> numbers = Arrays.asList(5, 12, 15, 8, 22);
List<Integer> result = numbers.stream()  // 将 List 转换成 Stream.filter(num -> num > 10)  // 过滤大于 10 的元素.collect(Collectors.toList());  // 收集结果为一个新的 ListSystem.out.println(result);  // 输出 [12, 15, 22]

通过 stream() 方法,我们将 List 转换成了一个 Stream,接着使用了 filter() 来过滤出大于 10 的元素,最后通过 collect() 方法将结果转回 List。

3. 流(Stream)的核心特点

  1. 声明式代码:你不需要关心具体的如何循环,Stream 把这些细节帮你处理了,你只需要专注于“做什么”而不是“怎么做”。
  2. 支持链式调用:你可以将多个操作连接在一起,像流水线一样一步步处理数据。
  3. 惰性求值:Stream 中的操作不会立即执行,直到你调用终端操作时,才会真正执行所有的操作。
  4. 可以并行处理:Stream 使得并行处理变得非常简单,特别适用于大数据量的处理。

4. Stream 的基本操作

Stream 主要有两类操作:中间操作终端操作

1. 中间操作(Intermediate Operations)

中间操作会返回一个新的 Stream,这意味着你可以连续链式调用多个中间操作。中间操作通常是懒执行的,只有在终端操作执行时,所有的中间操作才会一起执行。

常用的中间操作包括:

  • filter():过滤数据,返回符合条件的元素。
  • map():将每个元素转换成新的形式。
  • sorted():对数据进行排序。

示例
 

java">List<Integer> numbers = Arrays.asList(5, 12, 15, 8, 22);List<Integer> result = numbers.stream()        // 将 List 转换为 Stream.filter(num -> num > 10)  // 过滤出大于 10 的元素.map(num -> num * 2)      // 每个数字乘以 2.sorted()                 // 排序.collect(Collectors.toList());  // 收集结果为一个 ListSystem.out.println(result);  // 输出 [24, 30, 44]

在这个例子中,我们做了三件事:

  • 先过滤出大于 10 的数字。
  • 然后将每个数字乘以 2。
  • 最后对结果进行排序。
2. 终端操作(Terminal Operations)

终端操作是 Stream 处理的最后一步,执行完终端操作后,Stream 就会被消耗掉,无法继续使用。常见的终端操作有:

  • collect():将 Stream 中的元素收集成一个集合。
  • forEach():对每个元素执行某个操作。
  • reduce():将 Stream 中的所有元素聚合成一个结果(比如求和)。
  • count():统计元素的数量。

示例
 

java">List<Integer> numbers = Arrays.asList(5, 12, 15, 8, 22);// 1. collect():收集到 List 中
List<Integer> result = numbers.stream().filter(num -> num > 10).collect(Collectors.toList());
System.out.println(result);  // 输出 [12, 15, 22]// 2. forEach():打印每个元素
numbers.stream().forEach(num -> System.out.println(num));// 3. reduce():求和
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(sum);  // 输出 62

5. 延迟执行与惰性求值

Stream 的操作是惰性执行的,也就是说,Stream 中的操作并不会立即执行,而是等到你真正需要结果时(调用终端操作)才会执行。这种特性让我们可以做一些优化,比如避免不必要的操作。

示例
 

java">List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);// 中间操作:过滤和映射
Stream<Integer> stream = numbers.stream().filter(num -> num > 2)  // 过滤出大于 2 的数字.map(num -> num * 2);     // 每个数字乘以 2// 终端操作:打印结果
stream.forEach(System.out::println);  // 输出 6, 8, 10

在上面的代码中,filter()map() 是中间操作,只有在调用 forEach()(终端操作)时,才会实际进行数据处理。

6. 并行流(Parallel Stream)

Stream 还支持并行流(parallelStream()),它可以利用多核 CPU 的优势来加速处理。当你需要处理大量数据时,使用并行流可以显著提高效率。

示例
 

java">List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);// 使用 parallelStream() 进行并行处理
numbers.parallelStream().forEach(num -> System.out.println(num + " processed by " + Thread.currentThread().getName()));

总结

  • Stream 让你以声明式的方式处理数据,代码更加简洁和易读。
  • 中间操作(如 filtermap)是对流的转换,终端操作(如 collectforEach)才会触发数据的实际处理。
  • 惰性求值:Stream 的中间操作不会立即执行,而是直到终端操作调用时才会进行计算。
  • 并行流:Stream 支持并行处理,可以通过 parallelStream() 提升处理大量数据的效率。

http://www.ppmy.cn/server/150693.html

相关文章

第六章 状态模式优化代码

目录 一、场景概述 二、状态模式优化代码 一、场景概述 我们在日常开发过程中一定会遇到下述场景&#xff1a;业务中有类似订单这样需要修改状态的功能模块&#xff0c;订单状态的修改变化为 未支付 -> 已支付 -> 已完成 因此我们每次在修改状态之前&#xff0c;都得先…

React基础学习

React基础 &#x1f4e3; &#x1f4e3; &#x1f4e3; &#x1f4e2;&#x1f4e2;&#x1f4e2; ☀️☀️点开就是缘分认识一下&#xff0c;我是小冷。是一个兴趣驱动自学练习两年半的的Java工程师。 &#x1f4d2; 一位十分喜欢将知识分享出来的Java博主⭐️⭐️⭐️&#x…

OpenCV中的图片矫正

一、实验原理 基于计算机视觉中的透视变换&#xff08;Perspective Transformation&#xff09;&#xff0c;也称为单应性&#xff08;Homography&#xff09;。透视变换是一种几何变换&#xff0c;用于将图像从一个平面映射到另一个平面&#xff0c;同时保持直线的直线性。这种…

【机器学习算法】——决策树之集成学习:Bagging、Adaboost、Xgboost、RandomForest、XGBoost

集成学习 **集成学习(Ensemble learning)**是机器学习中近年来的一大热门领域。其中的集成方法是用多种学习方法的组合来获取比原方法更优的结果。 使用于组合的算法是弱学习算法&#xff0c;即分类正确率仅比随机猜测略高的学习算法&#xff0c;但是组合之后的效果仍可能高于…

uniapp h5 js设置监听:超时未操作返回首页(全局只监听一次,可设置监听事件+检查时间+超时时长)

功能实现: 可自定义超时时长,检查时间超时后跳转首页(/pages/home/index/index); 如果在首页,则不进行跳转监控状态下, 用户有任意操作(包括但不限于点击,滑动,跳转页面等),则重置监听,重新开始算时间超时方法及逻辑封装到单独的js文件中 全局只需在app.vue创建监听,其他页面无…

leetcode 面试经典 150 题:移除元素

链接移除元素题序号27类型数组解题方法双指针难度简单 题目 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k&#xff0c;要…

聊聊Oracle自适应查询优化

成也AQO败也AQO 因为工作的原因&#xff0c;我们接触到的客户大部分是金融和运营商行业&#xff0c;这些客户有个最大的特点是追求稳定&#xff0c;对于使用数据库新特性持保守的态度&#xff0c;不会轻易尝试某些可能会导致生产系统不稳定的新特性。上线前通常都会将一些新特…

SpringBoot【十】mybatis之xml映射文件>、<=等特殊符号写法!

一、前言&#x1f525; 环境说明&#xff1a;Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 在利用mybatis进行开发的时候&#xff0c;编写sql时可能少不了>、<等比较符号&#xff0c;但是在mapper映射文件中直接使用是不行的&#xff0c;会报错&#xff0…