探索Java 8 Stream API:现代数据处理的新纪元

Stream流

Stream初探:何方神圣?

Stream流是一种处理集合数据的高效工具,它可以让你以声明性的方式处理数据集合。Stream不是存储数据的数据结构,而是对数据源(如集合、数组)的运算操作概念,支持函数式编程风格

特性

  • 可以配合lambda写出简洁代码。
  • 链式操作:支持一系列中间操作(如filter, map)和最终操作(如forEach, collect),这些操作可以链接起来,形成一个管道来处理数据。
  • 延迟执行:中间操作不会立即执行,而是构建一个执行计划,直到遇到最终操作时才一次性完成所有操作,这种方式可以提高效率。
  • 并行处理:支持并行处理,通过调用parallelStream()方法,可以轻松地利用多核处理器的优势,无需手动编写多线程代码。
  • 类型安全:利用泛型,Stream操作可以在编译期检查类型错误,提高代码的安全性和可读性。

如何获得Stream流

Java提供了几种方式,可以让我们获得Stream流

  1. [集合创建流]Collection 接口的 stream()或 parallelStream()方法
  2. [自由值创建]静态的 Stream.of(…)、Stream.empty()方法
  3. [数组创建流]Arrays.stream(array)
  4. 静态的 Stream.generate()方法生成无限流,接受一个不包含引元的函数
  5. 静态的 Stream.iterate()方法生成无限流,接受一个种子值以及一个迭代函数
  6. Pattern 接口的 splitAsStream(input)方法
  7. 静态的 Files.lines(path)、Files.lines(path, charSet)方法
  8. 静态的 Stream.concat()方法将两个流连接起来
代码演示
          /** 三种常用获得流的方法* 1.Collection接口中的stream()方法* 2.Stream类的静态方法 of()* 3.Arrays工具类的stream(T[] array)方法**/// 用Collection接口中的stream()方法,获得流ArrayList<Integer> list = new ArrayList<>();// 创建集合list.add(1);list.add(2);list.add(3);Stream<Integer> stream1 = list.stream();// 获得流// 2.Stream类的静态方法 of()Stream<Integer> stream2 = Stream.of(1, 2, 3, 4);// 获得流//3.Arrays工具类的stream(T[] array)方法int[] arr = {1,2,3,4};IntStream stream3 = Arrays.stream(arr);// 获得流

Stream方法操作

Stream流就是流式处理数据,流的操作有很多种

  • 中间操作(真正处理数据的操作)
    • 中间操作就是执行完返回的是一个流,即可以**继续执行**流操作
    • 敲代码来说,就是使用中间操作的方法,写完继续再.调用其他方法
  • 终止操作(将操作完的结果返回)
    • 敲代码来说,调用终止方法,代码就结束;
操作函数说明
中间操作filter(Predicate)将结果为false的元素过滤掉
中间操作map(Function)转换元素的值,可以用方法引元或者lambda表达式
中间操作flatMap(Function)若元素是流,将流摊平为正常元素,再进行元素转换(合并两个流为一个流)
中间操作limit(long n)保留前n个元素
中间操作skip(long n)跳过前n个元素
中间操作concat(Stream s1, Stream s2)将两个流拼接起来
中间操作distinct()剔除重复元素
中间操作sorted()将Comparable元素的流排序
中间操作sorted(Comparator)将流元素按Comparator排序
中间操作peek(Consumer)流不变,但会把每个元素传入fun执行,可以用作调试
终结操作max(Comparator)取最大值
终结操作min(Comparator)取最小值
终结操作count()统计元素数量
终结操作findFirst()获得流的第一个元素
终结操作findAny()返回任意元素
终结操作anyMatch(Predicate)任意元素匹配时返回true
终结操作allMatch(Predicate)所有元素匹配时返回true
终结操作noneMatch(Predicate)没有元素匹配时返回true
终结操作reduce(Function)从流中计算某个值,接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数
终结操作iterator()迭代器迭代元素
终结操作forEach(Consumer)lambda的方式迭代
终结操作forEachOrdered(Consumer)可以应用在并行流上以保持元素顺序

5.2.1 中间操作

下面演示流的操作使用 - 中间操作

package day613.jdk8New.stream;import java.util.ArrayList;
import java.util.Comparator;
import java.util.stream.Stream;public class StreamAPITest {public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();// 创建集合list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);list.add(6);Stream<Integer> stream1 = list.stream();// 获得流/** void forEach(Consumer<? super T> action);* ---遍历流* ---参数类型:Consunmer* -----使用lambda重写Consumer接口的 void accept(T t)*///遍历流//stream1.forEach(t -> System.out.print(t + " "));// 1 2 3 4 5 6/** Stream<T> filter(Predicate<? super T> predicate);* ---过滤,即过滤掉不想要的数据,留下想要的* ---参数类型 Predicate* -----使用lambda重写Predicate接口的 boolean test(T t)*///过滤奇数,留下偶数//stream1.filter(t->t % 2 == 0).forEach(t-> System.out.print(t + " "));// 2 4 6/** <R> Stream<R> map(Function<? super T, ? extends R> mapper);* ---转换元素的值* ---参数类型 Function* -----使用lambda重写Function接口的 R apply(T t)*///将流中的整型转换成字符串类型,并遍历//stream1.map(t->String.valueOf(t)).forEach(t-> System.out.print(t + " "));//1 2 3 4 5 6/**  Stream<T> limit(long maxSize);* ---保留前maxSize个元素* ---参数类型 long*///保留前四个//stream1.limit(4).forEach(t-> System.out.print(t + " "));// 1 2 3 4/**   Stream<T> skip(long n);* ---跳过前n个元素* ---参数类型 long*///跳过前四个//stream1.skip(4).forEach(t-> System.out.print(t + " "));// 5 6/** Stream<T> sorted(Comparator<? super T> comparator);* ---排序* ---参数类型 Comparator* -----使用lambda重写Comparator接口的 int compare(T o1, T o2);*///降序排序stream1.sorted((o1,o2) -> o2 - o1 ).forEach(t-> System.out.print(t + " "));}}
练习:
给定ArrayList<Integer>集合,
先过滤数据只保留偶数,
后对数据进行降序排序,
去除重复元素,
将元素转成String类型
后将每个元素拼接上《》后输出 
  public static void test() {ArrayList<Integer> list = new ArrayList<>( );list.add(3);list.add(1);list.add(3);list.add(2);list.add(4);list.add(6);list.add(5);list.add(7);list.add(5);list.add(6);list.add(9);list.add(8);list.add(10);list.add(7);// 获得流Stream<Integer> stream = list.stream( );// 先过滤数据只保留偶数// 后对数据进行降序排序,// 去除重复元素,// 将元素转成String类型// 后将每个元素拼接上《》后输出stream.filter(e -> e % 2 == 0).sorted((o1,o2) -> o2 - o1).distinct().map(e -> String.valueOf(e)).forEach(e -> System.out.println("《"+e+"》" ));}

5.2.3 注意事项

Stream流的操作注意事项

  1. 流的操作只能使用一次,也就是说执行过终结操作后不能再继续使用

    否则报错报错IllegalStateException stream has already been closed

  2. 使用中间操作,返回新的流

  3. 没有终止操作,就不会有结果,换句话说,没有终结操作,中间操作是 不会执行的

	public static void test2() {Stream<Integer> stream = Stream.of(1, 2, 3);stream.filter((e) -> {System.out.println("正在过滤元素:"+e );return e % 2 == 0;});// 没有终结操作,中间的filter不会执行,输出语句不会执行}

在这里插入图片描述

5.3 流的收集

流操作完,将数据流中的数据再返回成数组和集合 --> 这就是收集流

将流收集到集合或数组中

  • collect() 收集到集合
    • collect(Collectors.toList( )) 将stream流中的数据,收集到List集合
    • collect(Collectors.toSet( )) 将stream流中的数据,收集到set集合
  • toArray 收集到数组
		ArrayList<Integer> list = new ArrayList<>( );list.add(3);// 获得流Stream<Integer> stream = list.stream( );// 先过滤数据只保留偶数// 后对数据进行降序排序,// 去除重复元素,// 将元素转成String类型// 变成ArrayList<String>返回List<String> list2 = stream.filter(e -> e % 2 == 0).sorted((o1, o2) -> o2 - o1).distinct( ).map(e -> String.valueOf(e)).collect(Collectors.toList( ));// 收集为List集合

最后

如果感觉有收获的话,点个赞 👍🏻 吧。
❤️❤️❤️本人菜鸟修行期,如有错误,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍在这里插入图片描述

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

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

相关文章

python绘制散点图

文章目录 1.实验目的2.需求3. 代码以及资源文件4.实验结果 1.实验目的 掌握Python绘图库matplotlib库 2.需求 3. 代码以及资源文件 import numpy as np import matplotlib.pyplot as plt import pandas as pd# 读取NPZ文件 data np.load(../Files/国民经济核算季度数据.npz…

cilium关闭vxlan

说明 操作 启用标志 yum -y install net-tools.x86_64 ifconfig | grep vxlan cilium_vxlan: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500修改相关配置 ks get cm cilium-config -oyaml | grep -E tunnel|ipv4-native-routing-cidr|auto-direct-node-routes…

[AIGC] Java List接口详解

List接口是Java集合框架的一部分&#xff0c;它是一个有序的集合&#xff0c;允许包含重复的元素。List接口在java.util包中&#xff0c;它扩展了Collection接口。本篇文章将详细介绍Java中List接口的常用API。 List接口的常用方法 以下列出了一些List接口的常用方法&#xf…

【OceanBase DBA早下班系列】—— 性能问题如何 “拍CT“ (一键获取火焰图和扁鹊图)

1. 前言 最近接连遇到几个客户的环境在排查集群性能问题&#xff0c;总结了一下&#xff0c;直接教大家如何去获取火焰图、扁鹊图&#xff08;调用关系图&#xff09;&#xff0c;直击要害&#xff0c;就像是内脏的疾病去医院看病&#xff0c;上来先照一个CT&#xff0c;通过分…

for循环结构

循环&#xff1a; 循环是一个重复执行一个代码的结构。只要满足循环的条件&#xff0c;会一直执行这个代码。 循环条件&#xff1a;在一定范围之内&#xff0c;按照指定的次数来执行循环。 循环体&#xff1a;在指定的次数内&#xff0c;执行的命令序列。只要条件满足&#…

【iOS】KVC相关总结

目录 1. 什么是KVC&#xff1f;2. 访问对象属性常用方法声明基础使用KeyPath路径多值操作 3. 访问集合属性4. 集合运算符自定义集合运算符 5. 非对象值处理访问基本数据类型访问结构体 6. 属性验证7. 设值和取值原理基本的Getter搜索模式基本的Setter搜索模式NSMutableArray搜索…

vue3+ele-plus+sortableJs对el-table使用sortableJs插件对表格拖拽时限定某列或某行不允许拖拽

如需有对el-table表格进行拖拽的需求&#xff0c;请点击&#xff1a; eleplus对el-table表格进行拖拽(使用sortablejs进行列拖拽和行拖拽)&#xff1a;-CSDN博客 如果你已实现拖拽需求&#xff0c;但拖拽后发现表头并未改变的话&#xff0c;请点击&#xff1a; 解决el-table表…

Windows本地使用SSH连接VM虚拟机

WIN10 VM17.5 Ubuntu:20.04 1.网路设置 1)选择编辑->更改设置 配置完成 2.修改了服务器文件&#xff0c;修改sshd配置&#xff0c;在此文件下/etc/ssh/sshd_config&#xff0c;以下为比较重要的配置 PasswordAuthentication yes PermitRootLogin yes PubkeyAuthenticat…

如何优雅地中断一个网络请求

在前端开发中&#xff0c;网络请求无处不在。但有时候&#xff0c;由于各种原因&#xff08;如用户取消操作、页面跳转等&#xff09;&#xff0c;我们需要中断正在进行的网络请求&#xff08;本文只针对前端实现&#xff09;。那么&#xff0c;如何优雅地实现这一功能呢&#…

C++学习笔记“类和对象”:多态;

目录 4.7 多态 4.7.1 多态的基本概念 4.7.2 多态案例--计算器类 4.7.3 纯虚函数和抽象类 4.7.4 多态案例二 - 制作饮品 4.7.5 虚析构和纯虚析构 4.7.6 多态案例三-电脑组装 4.7 多态 4.7.1 多态的基本概念 多态是C面向对象三大特性之一 多态分为两类 静志多态: 函数…

apex触发器满足条件时弹出对话框

在Salesforce中&#xff0c;Apex触发器是在记录的数据库操作&#xff08;如插入、更新、删除&#xff09;之前或之后执行的逻辑。由于Apex触发器运行在服务器端&#xff0c;无法直接触发客户端&#xff08;浏览器&#xff09;上的对话框。不过可以通过以下方法间接实现这一需求…

[ue5]建模场景学习笔记(6)——必修内容可交互的地形,交互沙(4)

1.需求分析&#xff1a; 现在我们已经有了可以在世界内近于无限的跑动痕迹&#xff0c;现在需要对痕迹进行细化&#xff0c;包括例如当人物跳起时便不再绘制痕迹&#xff0c;以及痕迹应该存在深浅&#xff0c;应该由两只脚分别绘制&#xff0c;同时也应该对地面材质进行进一步处…

程序性能分析:工具与策略

在软件开发中&#xff0c;程序性能分析是一个至关重要的环节。无论是为了确保代码的正确性&#xff0c;还是为了提高程序的运行效率&#xff0c;性能分析都是不可或缺的。本文将介绍程序性能分析的策略以及一系列性能分析和内存检查工具。 一、性能分析的策略 先保证正确性&a…

Vue基本使用-02

上节我们讲了什么是mvvm模型&#xff0c;以及我们vue的一些常用指令&#xff0c;今天给大家讲一下vue的基本使用&#xff0c;在将之前我们需要重点讲解我们的一个指令&#xff0c;v-model指令 v-model v-model 可以在组件上使用以实现双向绑定,什么是双向绑定呢?意思就是当我们…

景芯SoC A72的时钟树分析

innovus的ctslog中的Clock DAG信息可以报出来CTS主要运行步骤的关键信息&#xff0c;比如clustering&#xff0c;balancing做完后的clock tree的长度&#xff0c;clock tree上所用的buffer、inverter&#xff0c;icg cell数量&#xff0c;clock skew等信息。我们以景芯SoC A72 …

wordpress站群搭建2代码初始化

海鸥技术下午茶-wordpress站群搭建2项目代码初始化 1.后端环境 项目框架使用 go-zore https://go-zero.dev/docs/tasks 集成了各种工程实践的 web 和 rpc 框架。含极简的 API 定义和生成工具 goctl&#xff0c;可以根据定义的 api 文件一键生成 Go。可以很大程度上提高开发效…

代码随想录算法训练营第三十六天|LeetCode56 合并区间、LeetCode738 单调递增的数字

题1&#xff1a; 指路&#xff1a;56. 合并区间 - 力扣&#xff08;LeetCode&#xff09; 思路与代码&#xff1a; 相似于昨天的引爆气球(第三题)&#xff0c;这个题的题意更为清晰。我们只要取有交集元素的并集区间即可&#xff0c;其他区间照常返回。同样&#xff0c;我们…

React Router 路由详解

文章目录 1. 安装 react-router-dom2. 创建路由3. 创建链接和导航4. 渲染路由参数和查询字符串 在React中&#xff0c;我们通常使用 react-router-dom 这个库来处理路由。 1. 安装 react-router-dom 首先&#xff0c;你需要安装 react-router-dom &#xff0c;可以使用 npm 或…

Centos离线安装Python3

目录 1.准备工作 2.解压python压缩包 3.编译 4.安装、更改环境变量 5.建立pip连接 使用的是Centos7服务器&#xff0c;Py版本是py3.9.0 1.准备工作 首先确保服务器中存在相关的编译器&#xff0c;例如GCC&#xff1b;这里不做过多叙述&#xff0c;需要者前往&#xff1a…

自动化压测工具开发(MFC)

1. 背景 为了减轻测试人员在进行MFC程序压力测试时的重复手动操作&#xff0c;本文档描述了开发一个自动化压力测试工具的过程。该工具能够根据程序界面某块区域的预定状态变化&#xff0c;自动执行鼠标点击或键盘输入操作。 2. 技术概览 串口控制&#xff1a;用于控制外部设…