Jdk8 之 Stream流详细用法(一)

2023-11-18

本篇文章参考云深i不知处的文章
原文链接:https://blog.csdn.net/mu_wind/article/details/109516995
在这里插入图片描述

一、概述

  Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。

特点:

  1. 不是数据结构,不会保存数据。
  2. 不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。
  3. stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。

二、Stream流的创建

Stream 流可以通过集合和数组进行创建!
1、通过 java.util.Collection.stream() 方法用集合创建流

 		List<String> list = Arrays.asList("a", "b", "c");
        //创建一个顺序流
        Stream<String> stream = list.stream();
        //创建一个并行流
        Stream<String> stringStream = list.parallelStream();

2、使用 java.util.Arrays.stream(T[] array) 方法用数组创建流

        int[] arra = {1, 3, 5, 6, 8};
        IntStream stream = Arrays.stream(arra);

3、使用Stream的静态方法:of()、iterate()、generate()

		Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

        Stream<Integer> limit = Stream.iterate(0, (x) -> x + 3).limit(4);
        limit.forEach(System.out::println);

        Stream<Double> limit1 = Stream.generate(Math::random).limit(3);
        limit1.forEach(System.out::println);

结果:

0
3
6
9
0.8997037806521349
0.4208955236355437
0.5905370762238087

  第一种创建方式:streamparallelStream的简单区分: stream是顺序流,由主线程按顺序对流执行操作,而parallelStream是并行流,内部以多线程并行执行的方式对流进行操作,但前提是流中的数据处理没有顺序要求。例如筛选集合中的奇数,两者的处理不同之处:
在这里插入图片描述
如果流中的数据量足够大,并行流可以加快处速度。
除了直接创建并行流,还可以通过parallel()把顺序流转换成并行流:

Optional<Integer> findFirst = list.stream()
								.parallel().filter(x->x>6).findFirst();

三、Stream流的使用

在使用stream之前,先理解一个概念:Optional

Optional类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

3.1 遍历/匹配(foreach/find/match)

Stream也是支持类似集合的遍历和匹配元素的,只是Stream中的元素是以Optional类型存在的。Stream的遍历、匹配非常简单。
在这里插入图片描述

 List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);

        //便利符合条件的字符串
        list.stream().filter(x -> x > 6).forEach(System.out::println);

        //匹配到第一个
        Optional<Integer> first = list.stream().filter(x -> x > 6).findFirst();

        //匹配任意(适用于并行流)
        Optional<Integer> any = list.parallelStream().filter(x -> x > 6).findAny();

        //是否包含特殊条件元素
        boolean b = list.stream().anyMatch(x -> x > 6);

        System.out.println("匹配到第一个 ==> " + first.get());
        System.out.println("匹配任意(适用于并行流) ==> " + any.get());
        System.out.println("是否包含特殊条件元素 ==> " + b);

运行结果:

7
9
8
匹配到第一个 ==> 7
匹配任意(适用于并行流) ==> 7
是否包含特殊条件元素 ==> true

3.2 筛选(filter)

筛选,是按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。
在这里插入图片描述
案例一:筛选出Integer集合中大于6的元素,并打印出来

 		List<Integer> list = Arrays.asList(6,7,3,8,1,2,9);
        Stream<Integer> stream = list.stream();
        stream.filter(x -> x > 7).forEach(System.out::println);

结果:

8
9

案例二: 筛选员工中工资高于8000的人,并形成新的集合。 形成新集合依赖collect(收集)

private static List<Person> personList = new ArrayList<Person>();

    static {
        personList.add(new Person("Tom", 8900, 28, "male", "New York"));
        personList.add(new Person("Jack", 7000, 18, "male", "Washington"));
        personList.add(new Person("Lily", 7800, 8, "female", "Washington"));
        personList.add(new Person("Anni", 8200, 38, "female", "New York"));
        personList.add(new Person("Owen", 9500, 48, "male", "New York"));
        personList.add(new Person("Alisa", 7900, 68, "female", "New York"));
    }

    @Test
    public void getSalary() {
        List<String> collect = personList.stream()
                .filter(x -> x.getSalary() > 8000)
                .map(Person::getName)
                .collect(Collectors.toList());
        System.out.println("高于8000薪资到人员信息  ==>  " + collect);
    }
}

结果:

高于8000薪资到人员信息 ==> [Tom, Anni, Owen]

3.3 聚合(max/min/count)

max、min、count这些字眼你一定不陌生,没错,在mysql中我们常用它们进行数据统计。Java stream中也引入了这些概念和用法,极大地方便了我们对集合、数组的数据统计工作。
在这里插入图片描述
案例一:获取String集合中最长的元素。

    @Test
    public void listString() {
        List<String> list = Arrays.asList("adnm", "admmt", "pot", "xbangd", "weoujgsd");

        Optional<String> max = list.stream()
                .max(Comparator.comparing(String::length));
        System.out.println("最长的字符串 ==> " + max.get());
    }

结果:

最长的字符串 ==> weoujgsd

案例二:获取Integer集合中的最大值。

@Test
    public void listInteger() {
        List<Integer> list = Arrays.asList(7, 6, 9, 4, 11, 6);

        Optional<Integer> max = list.stream().max(Integer::compareTo);

        Optional<Integer> max1 = list.stream().max(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        });

        System.out.println("自然排序的最大值 ==> " + max.get());
        System.out.println("自定义排序的最大值 ==> " + max1.get());
    }

结果:

自然排序的最大值 ==> 11
自定义排序的最大值 ==> 11

案例三:获取员工工资最高的人。

    private static List<Person> personList = new ArrayList<Person>();

    static {
        personList.add(new Person("Tom", 8900, 28, "male", "New York"));
        personList.add(new Person("Jack", 7000, 18, "male", "Washington"));
        personList.add(new Person("Lily", 7800, 8, "female", "Washington"));
        personList.add(new Person("Anni", 8200, 38, "female", "New York"));
        personList.add(new Person("Owen", 9500, 48, "male", "New York"));
        personList.add(new Person("Alisa", 7900, 68, "female", "New York"));
    }

    @Test
    public void getMaxSalary() {
        Optional<Person> max = personList.stream()
                .max(Comparator.comparingInt(Person::getSalary));

        System.out.println("最高薪资到人员信息  ==>  " + max.get());
    }

结果:

最高薪资到人员信息 ==> Person(name=Owen, salary=9500, age=48, sex=male, area=New York)

案例四:计算Integer集合中大于6的元素的个数。

    @Test
    public void listIntegerCount() {
        List<Integer> list = Arrays.asList(7, 6, 9, 4, 11, 6);
        long count = list.stream().filter(x -> x > 6).count();

        System.out.println("list中大于6的元素个数 ==> " + count);
    }

结果:

list中大于6的元素个数 ==> 3

3.4 映射(map/flatMap)

映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap:

  • map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
  • flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
    在这里插入图片描述
    在这里插入图片描述
    案例一:英文字符串数组的元素全部改为大写。整数数组每个元素+3。
    @Test
    public void map() {
        String[] strArr = { "abcd", "bcdd", "defde", "fTr" };
        List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11);

        List<String> collect = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());
        List<Integer> collect1 = intList.stream().map(x -> x + 3).collect(Collectors.toList());

        System.out.println("每个元素大写:" + collect);
        System.out.println("每个元素+3:" + collect1);
    }

结果:

每个元素大写:[ABCD, BCDD, DEFDE, FTR]
每个元素+3:[4, 6, 8, 10, 12, 14]

案例二:将员工的薪资全部增加1000。

 private static List<Person> personList = new ArrayList<Person>();

    static {
        personList.add(new Person("Tom", 8900, 28, "male", "New York"));
        personList.add(new Person("Jack", 7000, 18, "male", "Washington"));
        personList.add(new Person("Lily", 7800, 8, "female", "Washington"));
        personList.add(new Person("Anni", 8200, 38, "female", "New York"));
        personList.add(new Person("Owen", 9500, 48, "male", "New York"));
        personList.add(new Person("Alisa", 7900, 68, "female", "New York"));
    }

    @Test
    public void saveSalary() {

        List<Person> collect = personList.stream().map(person -> {
            person.setSalary(person.getSalary() + 1000);
            return person;
        }).collect(Collectors.toList());
        collect.forEach(System.out::println);
    }

结果:

Person(name=Tom, salary=9900, age=28, sex=male, area=New York)
Person(name=Jack, salary=8000, age=18, sex=male, area=Washington)
Person(name=Lily, salary=8800, age=8, sex=female, area=Washington)
Person(name=Anni, salary=9200, age=38, sex=female, area=New York)
Person(name=Owen, salary=10500, age=48, sex=male, area=New York)
Person(name=Alisa, salary=8900, age=68, sex=female, area=New York)

案例三:将两个字符数组合并成一个新的字符数组。

    @Test
    public void str() {
        List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");

        List<String> collect = list.stream().flatMap(s -> {
            String[] split = s.split(",");
            Stream<String> stream = Arrays.stream(split);
            return stream;
        }).collect(Collectors.toList());

        System.out.println("处理前的集合:" + list);
        System.out.println("处理后的集合:" + collect);
    }

结果:

处理前的集合:[m,k,l,a, 1,3,5,7]
处理后的集合:[m, k, l, a, 1, 3, 5, 7]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Jdk8 之 Stream流详细用法(一) 的相关文章

随机推荐

  • 本地rabbitMQ安装并添加用户名

    环境 Windows10系统 1 本机安装rabbitMQ首先安装基于erlang语言支持的OTP软件 我直接用的 exe的安装包 2 安装rabbitMQ 记住软件的安装位置 3 进入rabbitMQ刚才的安装位置 进入到sbin目录下
  • android webview增强版,对原生webview的一些解决方案

    MWebView 根据 Tamicer JsWebView 修改定制 为什么要使用WebView 随着app业务的不断深入发展 只靠着原生代码来堆砌功能是不现实 毕竟开发的时长会增加 而且同时需要开发iOS和Android两套 并且 如果在
  • 华为OD机试单词加密(Python)

    题目 想象一下 你有一段英文句子 这句子里有很多的单词 每两个单词之间用一个空格隔开 现在 你要给这些单词打上一个 秘密标签 怎么打标签呢 如果单词里有元音字母 就是 a e i o u 大写的也算哦 那么把这些元音字母都换成星号 如果单词
  • Java类型转换工具类(十六进制—bytes互转、十进制—十六进制互转,String—Double互转)

    数据类型转换工具类 author cyf public class NumConvertUtil bytes 转16进制字符串 param bArray return public static final String bytesToHe
  • 动态规划经典例题

    01背包问题 有n个重量和价值分别为wi vi的物品 从这些物品中挑选出总重量不超过W的物品 求所有挑选方案中价值总和的最大值 限制条件 1 lt n lt 100 1 lt wi vi lt 100 1 lt W lt 10000 首先使
  • jetson nano 安装pytorch装不上

    可以尝试 先把依赖装上在安装whl文件 安装依赖的指令如下 sudo apt get install libopenblas base libopenmpi dev
  • 主成分分析PCA算法:为什么去均值以后的高维矩阵乘以其协方差矩阵的特征向量矩阵就是“投影”?

    这是从网上看到的PCA算法的步骤 第一步 分别求每列的平均值 然后对于所有的样例 都减去对应的均值 第二步 求特征协方差矩阵 第三步 求协方差的特征值 显示全部 关注者 1 218 被浏览 78 113 关注问题写回答 添加评论 分享 邀请
  • dncnn图像去噪_深度学习图像去噪发展概述

    深度学习图像去噪发展概述 由于深度学习 特别是卷积神经网络 CNN 在图像识别等领域取得了较好的成果 近年来 基于深度学习的图像去噪方法也被提出并得到了发展 2008年 Viren Jain等提出用CNN处理自然图像的去噪问题 21 得到了
  • 命令登录sql

    mysql h u p 例如 mysql h 10 38 162 22 u wd P 6657 p h 这里是host u 这里是username P 这里是port p 这里是 password
  • 在PyPI上发布自己的Python包(一)

    文章目录 发布PyPI 简单 0 GitHub 1 环境 2 准备 2 1 注册PyPI账号 2 2 安装环境 3 开始 3 1 新建文件夹 3 2 上传 3 3 测试 发布PyPI 简单 0 GitHub https github com
  • C++day2作业(2023.8.22)

    1 定义一个学生的结构体 包含学生的姓名 年龄 成绩 性别 学生的成绩 姓名 定义为私有权限 定义一个学生类型的结构体变量 设置公有函数用于给学生的成绩和名字进行赋值 结构体中的函数 结构体中声明 结构体外定义 include
  • UVa 12504 Updating a Dictionary

    Problem uva onlinejudge org index php option com onlinejudge Itemid 8 page show problem problem 3948 题意 貌似是模拟 Source Cod
  • 解读云原生的2021:抢占技术C位,迎来落地大爆发

    来源 InfoQ 作者 褚杏娟 2021年 云原生迎来黄金时代 本文是 2021 InfoQ 年度技术盘点与展望 系列文章 重点聚焦云原生领域在 2021 年的重要进展 动态 希望能帮助你准确把握 2021 年云原生领域的核心发展脉络 在行
  • r语言写九九乘法表并保存为txt文件

    r语言写九九乘法表并保存为txt文件 代码 for i in 1 9 for j in 1 i cat j x i i j t file 九九乘法表 txt append TRUE cat n file 九九乘法表 txt append T
  • Nacos-Server用户权限控制无效解决方案

    场景 nacos server默认账户是 nacos nacos 此用户权限太大 有时候为了安全起见会建立多个用户 给予不同的角色权限 但建立用户后发现权限不起作用 分析 nacos默认不开启权限控制 如果想使用权限控制功能 需要在 con
  • etp服务器怎么连接共享文件夹,Everything共享文件操作方法

    以前我们要想共享一些文件给朋友 最常见的方法就是通过网盘来完成 但是这样的共享并不是朋友们都喜欢的 其实利用著名的搜索工具Everything 我们就可以在电脑中划出一部分区域 从而快速搭建一个用于分享的服务器平台 这样我们可以将自己发现的
  • visual studio code怎么用root/sudo调试远程程序?

    vs code是款微软出品不错的编辑器 可以远程编辑 处理服务器上的文件 支持c php python java等各种语言 在调试c 程序 的时候遇到了一个问题 编辑代码是用的普通用户 但调试的时候需要用root启动 如果启动调试出现要求密
  • Python 安装模块后找不到模块以及Python代码自动补全设置的一个思路

    起因是在做一些小玩意时安装了一些模块 但是运行时却找不到模块 于是多次重装VScode里边的Python部分 导致VScode自动补全也被玩掉了 查了很久的才终于搞回来 先把找到的一个有用链接放这 免得找不到了如何使用Visual Stud
  • 使用labelme打标签,详细教程

    做图像语义分割 打标签时需要用到labelme这个工具 我总结了它的详细使用教程 目录 一 安装labelme工具 二 文件位置关系 三 labelme工具 四 labelme工具的快捷键 五 代码 将标签文件转为统一固定格式 六 总结 一
  • Jdk8 之 Stream流详细用法(一)

    本篇文章参考云深i不知处的文章 原文链接 https blog csdn net mu wind article details 109516995 一 概述 Stream 是 Java8 中处理集合的关键抽象概念 它可以指定你希望对集合进