Java中的Stream

1. 什么是 Stream?

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

2. 为什么要使用 Stream?

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

传统做法:

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

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 让你可以通过一系列简单的“流式操作”来处理数据。
 

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():对数据进行排序。

示例
 

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():统计元素的数量。

示例
 

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 中的操作并不会立即执行,而是等到你真正需要结果时(调用终端操作)才会执行。这种特性让我们可以做一些优化,比如避免不必要的操作。

示例
 

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 的优势来加速处理。当你需要处理大量数据时,使用并行流可以显著提高效率。

示例
 

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.mzph.cn/bicheng/63906.shtml

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

相关文章

使用 Kubernetes 部署 Redis 主从及 Sentinel 高可用架构(未做共享存储版)

文章目录 使用 Kubernetes 部署 Redis 主从及 Sentinel 高可用架构Redis 主从架构部署 (1.yaml)Redis Sentinel 部署 (2.yaml)Sentinel 服务暴露 (3.yaml)部署步骤总结 使用 Kubernetes 部署 Redis 主从及 Sentinel 高可用架构 本文将详细介绍如何在 Kubernetes 中部署 Redis …

ElasticSearch常见的索引_集群的备份与恢复方案

方案一&#xff1a;使用Elasticsearch的快照和恢复功能进行备份和恢复。该方案适用于集群整体备份与迁移&#xff0c;包括全量、增量备份和恢复。 方案二&#xff1a;通过reindex操作在集群内或跨集群同步数据。该方案适用于相同集群但不同索引层面的迁移&#xff0c;或者跨集…

GauHuman阅读笔记【3D Human Modelling】

笔记目录 1. 基本信息2. 理解(个人初步理解,随时更改)3. 精读SummaryResearch Objective(s)Background / Problem StatementMethod(s)EvaluationConclusionReferences1. 基本信息 题目:GauHuman: Articulated Gaussian Splatting from Monocular Human Videos时间:2023.12…

onlyoffice 容器配置修改后制作镜像导出以及上传到 dockerhub

1.将容器制作成新的镜像 docker commit -p -a "xxx" -m "zh-cn-20-100" onlyoffice ooffice:7.1.1.23docker commit: 这是 Docker 中用于创建新镜像的命令。 -p: 这个选项用于在提交之前暂停容器的运行。这可以确保数据的完整性&#xff0c;因为容器在提交…

CentOS7环境安装php

直接安装 yum -y install php CentOS7默认安装是php5&#xff0c;现在php已有8.3版本 先查看php -v 版本 如果是低版本&#xff0c;可以删除 yum remove php yum remove php-fpm yum remove php-common 一、添加REMI存储库 yum install epel-release yum install -y …

ByteByteGo-Top 9 HTTP Request Methods 9种HTTP请求方法

更详细准确的描述直接参考 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/CONNECT ​​​​​本片文章出自 EP85: Top 9 HTTP Request Methods - ByteByteGo Newsletter http request methods 1&#xff0c;GET 从服务器获取资源。 具有幂等性&#xff08;idempo…

HarmonyOS:多线程并发-Worker

Worker主要作用是为应用程序提供一个多线程的运行环境&#xff0c;可满足应用程序在执行过程中与宿主线程分离&#xff0c;在后台线程中运行一个脚本进行耗时操作&#xff0c;极大避免类似于计算密集型或高延迟的任务阻塞宿主线程的运行。具体接口信息及使用方法详情请见Worker…

Linux 升级 openssh 方法步骤

目录 一&#xff1a;OpenSSH 介绍二&#xff1a;升级 OpenSSH1、下载源码包2、查看当前安装位置3、上传源码包4、生成Makefile文件5、编译并安装6、重启ssh服务7、检查版本信息 一&#xff1a;OpenSSH 介绍 OpenSSH最初是作为OpenBSD系统项目的一部分而开发的&#xff0c;后面…

ES语句——DSL(kibana语句)

一、查询操作 查看当前索引的数据结构 _mapping Get ai-open-log*/_mapping 查询当前索引下的文档数以及分片信息 _count Get ai-open-log*/_count { "count": 12345, //当前索引下的文档总数 "_shards": { //分片信息 "total&…

docker开启远程访问

1、编辑docker.server文件 vi /usr/lib/systemd/system/docker.service 找到 [Service] 节点&#xff0c;修改 ExecStart 属性&#xff0c;增加 -H tcp://0.0.0.0:2375 ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock -H tcp://0.0.0.0:2…

ubuntu检测是否已安装nvidia驱动以及产品类型

nvidia-sminvidia-smi 是 NVIDIA 提供的一个命令行工具&#xff0c;用于查看和管理 NVIDIA GPU 的状态。当你运行 nvidia-smi 命令时&#xff0c;它会显示当前系统中所有 NVIDIA GPU 的状态信息&#xff0c;包括 GPU 的使用率、温度、内存使用情况等。 有8个GPU nvcc -V查看c…

python的自动化seleium安装配置(包含谷歌的chromedriver)

目录 前言介绍 一、下载谷歌浏览器chromedriver (一)查看谷歌浏览器版本 (二)去官网下载谷歌驱动(chromdriver) (三)谷歌浏览器安装位置解压 (四)配置环境变量 二、pychram里下载安装selenium 三、测试selenium是否成功 前言介绍 Selenium是一个开源的自动化测试工具&…

基础学习:(5)不同卷积:transposed convolution,deconvolution,dilated convolution

基础学习&#xff1a;&#xff08;5&#xff09;不同卷积 文章目录 基础学习&#xff1a;&#xff08;5&#xff09;不同卷积前言1 deconvlution transposed convolution2 对比2.1 Convolution animations2.2 Transposed convolution animations2.3 Dilated convolution 前言 …

轻量级日志管理平台:Grafana Loki搭建及应用(详细篇)

前言 Grafana Loki是Grafana Lab团队提供的一个水平可扩展、高可用性、多租户的日志聚合系统&#xff0c;与其他日志系统不同的是&#xff0c;Loki最初设计的理念是为了为日志建立标签索引&#xff0c;而非将原日志内容进行索引。 现在目前成熟的方案基本上都是&#xff1a;L…

【java】在 Java 中使用 Jackson 或 Gson 库来实现对象和 JSON 之间的转换

1. 使用 Jackson 库 a. 将 Java 对象转为 JSON 字符串 import com.fasterxml.jackson.databind.ObjectMapper;public class Main {public static void main(String[] args) throws Exception {Person person new Person("John", 30);// 创建 ObjectMapper 对象Obj…

[漏洞挖掘与防护] 05.CVE-2018-12613:phpMyAdmin 4.8.1后台文件包含缺陷复现及防御措施

这是作者新开的一个专栏——“漏洞挖掘与防护”,前期会复现各种经典和最新漏洞,并总结防护技巧;后期尝试从零学习漏洞挖掘技术,包括Web漏洞和二进制及IOT相关漏洞,以及Fuzzing技术。新的征程,新的开启,漫漫长征路,偏向虎山行。享受过程,感谢您的陪伴,一起加油~ 欢迎关…

el-table行合并及合并后序号处理

效果图 <el-tableclass"ncky-detail-table"v-loading"tableLoading"border:data"tableDataVo":span-method"objectSpanMethod"row-key"uniqueFlag":row-class-name"tablerowclassname"><el-table-column…

vue-echarts高度缩小时autoresize失效

背景 项目中采用动态给x-vue-echarts style赋值width&#xff0c;height的方式实现echarts图表尺寸的改变 <v-chart...autoresize></v-chart>给v-chart添加autoresize后&#xff0c;在图表宽度变化&#xff0c;高度增加时无异常&#xff0c;高度减小时图表并未缩…

Ubuntu 挂载目录

1. 临时挂载&#xff08;重启后失效&#xff09; 创建挂载点&#xff1a; $ sudo mkdir -p /work临时挂载磁盘到 work 目录&#xff1a; $ sudo mount /dev/nvme0n1p1 /work验证挂载是否成功&#xff1a; $ df -h /work此方法挂载在系统重启后会失效&#xff0c;需手动重新挂载…

厦门凯酷全科技有限公司正规吗靠谱吗?

随着短视频和直播电商的迅猛发展&#xff0c;越来越多的企业开始将目光投向抖音这一平台。作为国内领先的短视频社交平台&#xff0c;抖音凭借其庞大的用户基础和强大的算法推荐系统&#xff0c;成为众多品牌拓展市场、提升销售的重要渠道。厦门凯酷全科技有限公司&#xff08;…