探索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集合

最后

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

❤vue2项目webpack打包的优化策略

❤ vue2项目webpack打包的优化策略 &#xff08;优化前&#xff09; 现在我们的打包时间为&#xff1a; >打包体积大小为&#xff1a; 1、去除开发环境和生产环境提示以及日志 开发环境和生产环境的打印处理 生产环境去除console.log打印的两种方式 通过环境变量控制co…

一张图读懂天然气气源

一张图读懂天然气气源

《pvz植物大战僵尸杂交版》V2.0.88整合包火爆全网,支持安卓、ios、电脑等!

今天来给大家安利一款让人欲罢不能的游戏——《植物大战僵尸杂交版》2.0.88版。这可不是普通的植物大战僵尸&#xff0c;它可是席卷了B站&#xff0c;火爆全网的存在&#xff01; 先说说这个版本&#xff0c;它可是网络上现存最全的植物大战僵尸杂交版整合包。里面不仅有修改工…

tkinter文本对齐方式

tkinter文本对齐方式 文本对齐方式效果代码 文本对齐方式 左对齐&#xff08;left&#xff09;&#xff1a;默认对齐方式&#xff0c;文本从左边界开始。右对齐&#xff08;right&#xff09;&#xff1a;文本从右边界开始。居中对齐&#xff08;center&#xff09;&#xff1…

NVIDIA MPS详解

NVIDIA 文章目录 NVIDIANVIDIA MPS介绍一、MPS作用二、MPS实例MPS与Hyper-Q区别Pascal架构和Volta架构不同架构上的MPS实现MPS基准测试MPS的使用MPS组成MPS执行过程开启与关闭MPS Volta MPS资源配置公平性MPS程序示例编写开启MPS脚本编写执行程序编写关闭MPS脚本运行MPS脚本运行…

linux部署运维3——centos7.9离线安装部署配置涛思taos2.6时序数据库TDengine以及java项目链接问题处理(二)

上一篇讲了centos7.9如何安装涛思taos2.6时序数据库的操作步骤和方案&#xff0c;本篇主要讲解taos数据库的初始化&#xff0c;相关配置说明&#xff0c;数据库和表的创建问题以及java项目连接问题。 centos7.9如何离线安装taos2.6&#xff0c;请点击下方链接详细查看&#xf…

新疆在线测宽仪配套软件实现的9大功能!

在线测宽仪可应用于各种热轧、冷轧板带材的宽度尺寸检测&#xff0c;材质不限&#xff0c;木质、钢制、铁质、金属、纸质、塑料、橡胶等都可以进行无损非接触式的检测&#xff0c;在各式各样的产线应用中&#xff0c;有些厂家&#xff0c;需要更加详尽完备的分析信息&#xff0…

离散化——Acwing.802区间和

离散化 定义 离散化可以简单理解为将连续的数值或数据转换为离散的、有限个不同的值或类别。离散化就是将一个可能具有无限多个取值或在一个较大范围内连续取值的变量&#xff0c;通过某种规则或方法&#xff0c;划分成若干个离散的区间或类别&#xff0c;并将原始数据映射到…

【Go】用 Go 原生以及 Gorm 读取 SQLCipher 加密数据库

本文档主要描述通过 https://github.com/mutecomm/go-sqlcipher 生成和读取 SQLCipher 加密数据库以及其中踩的一些坑 用 go 去生成读取 SQLCipher 数据库用 gorm 去读取 SQLCipher 数据库在生成后分别用 DBeaver、db browser 和 sqlcipher 读取 SQLCipher 数据库&#xff0c;…

基于jeecgboot-vue3的Flowable流程-流程处理(二)

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 对应VForm3&#xff0c;原先的后端解析也要做调整 1、获取历史任务的表单信息 // 获取历史任务节点表单数据值List<HistoricVariableInstance> listHistoricVariableInstance his…

Python第二语言(十二、SQL入门和实战)

目录 1. Python中使用MySQL 1.1 pymysql第三方库使用MySQL 1.2 连接MySQL 1.3 操作数据库&#xff0c;创建表 1.4 执行查询数据库语句 2. python中MySQL的插入语句 2.1 commit提交 2.2 自动提交 3. pymysql案例 3.1 数据内容 3.2 DDL定义 3.3 实现步骤 3.4 文件操…

最小生成树kruskal算法详解

kruskal算法的思想简单来说就是&#xff1a;每次选择图中最小边权的边&#xff0c;如果边两端的顶点不在相同的连通块中&#xff0c;就把这条边加入到最小生成树中。 具体实现如下&#xff1a; 首先是边的定义&#xff0c;需要判断边的两个端点是否在不同的连通块中&#xff…

Vue前端ffmpeg压缩视频再上传(全网唯一公开真正实现)

1.Vue项目中安装插件ffmpeg 1.1 插件版本依赖配置 两个插件的版本 "ffmpeg/core": "^0.10.0", "ffmpeg/ffmpeg": "^0.10.1"package.json 和 package-lock.json 都加入如下ffmpeg的版本配置&#xff1a; 1.2 把ffmpeg安装到项目依…

深入探究MySQL游标(Cursor)

前言 MySQL游标&#xff08;Cursor&#xff09;是MySQL中用于处理查询结果的一种机制。游标允许我们在查询结果集中逐行处理数据&#xff0c;而不是一次性获取所有数据。这对于处理大量数据非常有用&#xff0c;因为它可以减少内存消耗并提高性能。在MySQL中&#xff0c;游标主…

【源码】【Spring+SpringMVC+MyBatis】电子商城网上购物平台的设计与开发

学生成绩管理系统 系统功能开发环境开发技术前端技术后端技术 系统展示登录界面注册界面系统首页商品详情页下单界面付款界面购物车界面 源码获取↓↓↓↓&#xff1a; 源码可在后台私信联系博主或文末添加博主微信获取帮助 系统功能 登录、注册模块&#xff1a;如果用户第一次…

udp协议下的socket函数

目录 1.网络协议 2.网络字节序 3.socket编译接口 4.sockaddr结构体 5.模拟实现 1.socket函数 2.bind函数&#xff08;绑定&#xff09; 1.讲解 1.如何快速的将 整数ip<->字符串 2.ip地址的注意事项 3.端口号的注意事项 3.recvfrom函数 4.sendto函数 5.代码呈…

C++ Primer 第五版 第16章 模板与泛型编程

模板是C中泛型编程的基础。一个模板就是一个创建类或函数的蓝图或者说公式。当使用一个vector这样的泛型类型&#xff0c;或者find这样的泛型函数时&#xff0c;我们提供足够的信息&#xff0c;将蓝图转换为特定的类或函数。这种转换发生在编译时。 一、定义模板 1. 函数模板…

Airtest 使用指南

Airtest 介绍 准备工作 AirtestIDE 安装与启动: https://airtest.doc.io.netease.com/IDEdocs/getting_started/AirtestIDE_install/ 电脑端的准备工作完成后,对于手机端只需要打开允许USB调试,当首次运行时会提示安装PocoService,同意即可。 界面介绍

【CT】LeetCode手撕—53. 最大子数组和

目录 题目1-思路2- 实现⭐53. 最大子数组和——题解思路 3- ACM 实现 题目 原题连接&#xff1a;53. 最大子数组和 1-思路 动规五部曲 1. 定义 dp 数组 dp[i] 含义为&#xff1a;下标为 i 的数组的最大子数组和 2. 递推公式 因为所求的是最大子数组的和&#xff0c;即当前 n…

群辉其它远程访问方案(Cpolar篇)

目录 1、下载NAS套件安装包 2、手动安装 3、配置 4、访问 &#xff08;1&#xff09;网页 &#xff08;2&#xff09;手机管家 &#xff08;3&#xff09;助手 &#xff08;4&#xff09;DS File 群辉的远程访问&#xff0c;最标准的做法就是使用群辉自己的DDNS&#x…