当前位置:

首页 > 编程开发 > Java 8 中 Stream 的使用方式是什么?

Java 8 中 Stream 的使用方式是什么?

本文目录

    1.为什么有经验的老手更倾向于使用Stream性能优势,(大数据量)相较于迭代器,速度更快支持串行与并行处理,并行处理更能充分利用CPU的资源Stream是一种计算数据的流,它本身不会存储数据支持函数式编程代码优雅,让代码更高效,干净,简洁2.Stream的使用方式三步操作:创建Stream中间操作终止操作3.Stream的创建Stream的创建都会依赖于数据源,通常是容器或者数组Stream流的创建大致分为4中,最为常用的就是通过集合创建importjava.util.ArrayList;importj

    1. 为什么有经验的老手更倾向于使用Stream

    • 性能优势,(大数据量)相较于迭代器,速度更快

    • 支持串行与并行处理,并行处理更能充分利用CPU的资源

    • Stream 是一种计算数据的流,它本身不会存储数据

    • 支持函数式编程

    • 代码优雅,让代码更高效,干净,简洁

    2. Stream 的使用方式

    三步操作:

    • 创建Stream

    • 中间操作

    • 终止操作

    3. Stream 的创建

    Stream 的 创建都会依赖于数据源,通常是容器或者数组 Stream 流的创建大致分为4中,最为常用的就是通过集合创建

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    public class CreateStreamDemo {
        public static void main(String[] args) {
            // 1 通过集合创建Stream也是用的最多的一种形式
            List strList = new ArrayList<>();
            strList.add("a");
            strList.add("b");
            strList.add("c");
            // 创建串行操作流
            Stream stream = strList.stream();
            // 创建并行操作流
            Stream parallelStream = strList.parallelStream();
            // 2 通过数组创建Stream
            int[] arr = new int[]{1,2,3};
            IntStream intStream = Arrays.stream(arr);
            // 3 通过Stream.of
            Stream integerStream = Stream.of(1,2,3);
            Stream stringStream = Stream.of("a","b","c");
            // 4 无限流
            // 每隔五个数取一个
            Stream.iterate(0, t -> t + 5).forEach(System.out::println); // 迭代
            Stream.generate(Math::random).forEach(System.out::println); // 生成
        }
    }

    4. Stream 中间操作

    Stream 中间操作,我们最为常用的就是过滤,去重,排序 本章包含我们开发最常用的对对象的去重,和更据对象中的对个属性组合排序

    import com.zhj.java8.bean.Student;
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.List;
    import java.util.TreeSet;
    import java.util.stream.Stream;
    import static java.util.stream.Collectors.collectingAndThen;
    import static java.util.stream.Collectors.toCollection;
    
    public class MiddleStreamDemo {
        public static void main(String[] args) {
            List students = new ArrayList<>();
            students.add(new Student(1,"小华",23,1));
            students.add(new Student(1,"小华",23,2));
            students.add(new Student(2,"小米",20,2));
            students.add(new Student(3,"小果",30,3));
            students.add(new Student(4,"小维",18,2));
            // 过滤
            students.stream().filter(stu -> stu.getAge() > 20).forEach(System.out::println);
            // 去重
            // 对对象去重是根据引用去重,内容重复并不会去重,除非重写equals和hashCode方法
            System.out.println("----------去重----------");
            System.out.println("去重1----------");
            students.stream().distinct().forEach(System.out::println);
            // 对集合中对象某些属性去重,不重写equals和hashCode方法,只能借助其他数据结构来辅助去重
            // 单个属性可以stu -> stu.getId()
            // 多个属性可以stu -> stu.getId() + ";" + stu.getName()
            System.out.println("去重2----------");
            ArrayList distinctList = students.stream().collect(
                    collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(stu -> stu.getId() + ";" + stu.getName()))), ArrayList::new)
            );
            distinctList.stream().forEach(System.out::println);
            // 排序 支持定义排序方式
            // sorted 默认使用 自然序排序, 其中的元素必须实现Comparable 接口
            System.out.println("----------排序----------");
            System.out.println("排序1----------");
            students.stream().sorted().forEach(System.out::println);
            // sorted(Comparator comparator) :我们可以使用lambada 来创建一个Comparator 实例。可以按照升序或着降序来排序元素。
            System.out.println("排序2----------");
            students.stream()
                    .sorted(Comparator.comparing(Student::getAge,Comparator.reverseOrder())) // ,Comparator.reverseOrder() 逆序
                    .forEach(System.out::println);
            // 创建比较器,通过对比较器内容的定义实现对多个属性进行排序,类似sql中连续的orderBy
            System.out.println("排序3----------");
            students.stream().sorted(
                    (s1,s2) -> {
                        if (s1.getAge() == s2.getAge()) {
                            return s1.getSex().compareTo(s2.getSex());
                        } else {
                            return -s1.getAge().compareTo(s2.getAge());
                        }
                    }
            ).forEach(System.out::println);
            System.out.println("排序4----------");
            Comparator studentComparator = (s1,s2) -> {
                Integer age1 = s1.getAge();
                Integer age2 = s2.getAge();
                if (age1 != age2) return age1 - age2;
                Integer sex1 = s1.getSex();
                Integer sex2 = s2.getSex();
                if (sex1 != sex2) return sex2 - sex1;
                return 0;
            };
            students.stream().sorted(studentComparator).forEach(System.out::println);
            // 截取 截取前三个元素
            System.out.println("----------截取----------");
            students.stream().limit(3).forEach(System.out::println);
            // 跳过 跳过前3个元素
            System.out.println("----------跳过----------");
            students.stream().skip(3).forEach(System.out::println);
            // 映射
            System.out.println("----------映射----------");
            System.out.println("映射Map----------");
            // map接收Lambda,将元素转换其他形式,或者是提取信息,并将其映射成一个新的元素
            Stream> streamStream1 = students.stream().map(str -> filterStudent(str));
            streamStream1.forEach(sm -> sm.forEach(System.out::println));
            System.out.println("映射flatMap----------");
            // map接收Lambda,将流中的每一个元素转换成另一个流,然后把所有流连成一个流 扁平化映射
            Stream studentStream2 = students.stream().flatMap(str -> filterStudent(str));
            studentStream2.forEach(System.out::println);
            // 消费
            System.out.println("----------消费----------");
            students.stream().peek(stu -> stu.setAge(100)).forEach(System.out::println);
        }
        public static Stream filterStudent(Student student) {
            student = new Student();
            return Stream.of(student);
        }
    }

    Student

    public class Student implements Comparable {
        private Integer id;
        private String name;
        private Integer age;
        private Integer sex;
        public Student() {
        }
        public Student(Integer id, String name, Integer age, Integer sex) {
            this.id = id;
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
        public Integer getSex() {
            return sex;
        }
        public void setSex(Integer sex) {
            this.sex = sex;
        }
        @Override
        public String toString() {
            return "Student{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    ", age='" + age + '\'' +
                    ", sex=" + sex +
                    '}';
        }
        @Override
        public int compareTo(Student o) {
            return this.getAge() - o.getAge();
        }
    }

    5. Stream 终止操作

    Stream 的终止操作,最常用的就是讲处理过的数据收集到新的容器中,同时可以实现向Sql聚合函数,分组的一些效果

    package com.zhj.java8.stream;
    import com.zhj.java8.bean.Student;
    import java.util.*;
    import java.util.stream.Collectors;
    public class TerminationStreamDemo {
        public static void main(String[] args) {
            List students = new ArrayList<>();
            students.add(new Student(1,"小华",23,1));
            students.add(new Student(2,"小米",20,2));
            students.add(new Student(3,"小果",30,3));
            students.add(new Student(4,"小维",18,2));
            students.add(new Student(5,"小华",23,2));
            System.out.println("--------------------匹配聚合操作--------------------");
            // allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
            boolean allMatch = students.stream().allMatch(stu -> stu.getAge() > 10);
            System.out.println("全部符合大于10岁条件:" + allMatch);
            // noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
            boolean noneMatch = students.stream().noneMatch(stu -> stu.getAge() > 10);
            System.out.println("全部不符合大于10岁条件:" + noneMatch);
            // anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
            boolean anyMatch = students.stream().anyMatch(stu -> stu.getAge() > 20);
            System.out.println("含有任意符合大于20岁条件:" + anyMatch);
            // findFirst:返回流中第一个元素
            Student findFirst = students.stream().findFirst().get();
            System.out.println("第一个学生:" + findFirst);
            // findAny:返回流中的任意元素
            Student findAny = students.stream().findAny().get();
            System.out.println("任意一个学生:" + findAny);
            //  count:返回流中元素的总个数
            long count = students.stream().count();
            System.out.println("学生总数:" + count);
            // max:返回流中元素最大值
            Student max = students.stream().max(Student::compareTo).get();
            System.out.println("年龄最大学生:" + max);
            // max:返回流中元素最大值
            Student min = students.stream().min(Student::compareTo).get();
            System.out.println("年龄最小学生:" + min);
            System.out.println("--------------------规约操作--------------------");
            System.out.println("学生年龄总和:" + students.stream().map(Student::getAge).reduce(Integer::sum));
            System.out.println("学生年龄最大:" + students.stream().map(Student::getAge).reduce(Integer::max));
            System.out.println("--------------------收集操作--------------------");
            List list = students.stream().collect(Collectors.toList());
            Set set = students.stream().collect(Collectors.toSet());
            Map map = students.stream().collect(Collectors.toMap(Student::getId, Student::getName));
            String joinName = students.stream().map(Student::getName).collect(Collectors.joining(",", "(", ")"));
            // 总数
            students.stream().collect(Collectors.counting());
            // 最大年龄
            students.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get();
            // 年龄和
            students.stream().collect(Collectors.summingInt(Student::getAge));
            // 平均年龄
            students.stream().collect(Collectors.averagingDouble(Student::getAge));
            // 信息合集
            DoubleSummaryStatistics statistics = students.stream().collect(Collectors.summarizingDouble(Student::getAge));
            System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());
            // 分组
            Map> collect = students.stream().collect(Collectors.groupingBy(Student::getSex));
            System.out.println(collect);
            //多重分组,先根据性别分再根据年龄分
            Map>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge)));
            //分区
            //分成两部分,一部分大于20岁,一部分小于等于20岁
            Map> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 20));
            //规约
            Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get();
            System.out.println(allAge);
        }
    }

    6. Stream 特性

    中间操作惰性执行

    多个中间操作的话,不会多次循环,多个转换操作只会在终止操作的时候融合起来,一次循环完成。

    • 内部迭代

    • 找到符合条件的数据后边的迭代不会进行

    • 流的末端操作只有一次

    异常:stream has already been operated upon or closed

    意思是流已经被关闭了,这是因为当我们使用末端操作之后,流就被关闭了,无法再次被调用,如果我们想重复调用,只能重新打开一个新的流。

    本文内容来源于网友投稿,如有侵权请联系删除。
    作者最新文章
    编程开发 Java
    相关文章 更多
    Claude Code AI编程工具实力揭秘与编程助手实测
    Claude Code AI编程工具实力揭秘与编程助手实测

    通过实测展示Claude Code在终端中如何理解自然语言指令、自动修改代码文件并处理复杂编程任务,帮助开发者评估其实际辅助能力。

    winforms教程自学入门与基础开发步骤详解
    winforms教程自学入门与基础开发步骤详解

    本教程详细讲解如何使用Visual Studio创建WinForms项目,通过添加按钮和标签控件并编写点击事件代码,实现一个基础的计数器功能,适合C#初学者快速上手Windows窗体应用开发。

    Cursor自动补全设置教程教你快速开启代码补全功能
    Cursor自动补全设置教程教你快速开启代码补全功能

    详解Cursor编辑器中自动补全功能的开启与优化设置,涵盖Tab触发机制、上下文窗口调整及模型切换,帮助开发者解决补全延迟、干扰大等问题,提升编码流畅度。

    pandas的数据格式怎么转换和设置方法教程
    pandas的数据格式怎么转换和设置方法教程

    详解Pandas中数据格式转换的核心方法,包括astype强制转换、to_numeric容错处理及日期解析技巧,解决常见类型错误并提升数据处理效率。

    VS Code中文设置方法 简体语言包安装与切换教程
    VS Code中文设置方法 简体语言包安装与切换教程

    详细介绍在Visual Studio Code中安装Chinese (Simplified)语言包的方法,包括通过扩展市场搜索、安装及自动重启切换至简体中文界面的完整步骤,帮助开发者快速将编辑器本地化。

    cursor安装过程无法更改安装位置的解决方法
    cursor安装过程无法更改安装位置的解决方法

    针对Cursor安装包默认锁定C盘且无路径选择界面的问题,提供通过手动移动文件并创建目录联结(Symbolic Link)的解决方案,实现将软件安装在其他磁盘分区。

    rust下载安装教程详解及Windows环境配置方法
    rust下载安装教程详解及Windows环境配置方法

    详解Windows系统下Rust语言的安装步骤,重点解析rustup工具链管理机制,解决环境变量配置错误及MSVC链接器缺失问题,提供可复制的命令验证方法与常见报错的因果排查思路。

    vs code怎么配置 chat实用设置教程步骤
    vs code怎么配置 chat实用设置教程步骤

    详解VS Code中Chat插件的安装与核心配置步骤,重点解决API连接失败、响应慢等常见问题,通过优化上下文设置提升代码生成质量,适合希望集成AI辅助工具的开发者阅读。

    uniapp实例教程代码详解与项目实战指南
    uniapp实例教程代码详解与项目实战指南

    本教程通过实战案例详解UniApp开发流程,包括项目初始化、页面结构解析、数据绑定与事件处理,帮助初学者快速上手跨平台应用开发。

    android studio安装教程2026
    android studio安装教程2026

    详细讲解2026年最新版Android Studio的下载与安装步骤,涵盖JDK环境检查、组件选择及初始配置,助您顺利开启安卓应用开发之旅。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    macOS软件
    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    Mac软件 更多
    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。

    灵活计算器
    灵活计算器
    macOS/iOS/Android

    灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

    赤友清理大师
    赤友清理大师
    macOS

    赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    WINDOWS 更多
    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。

    Windows 10
    Windows 10
    Windows

    Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

    极度公式
    极度公式
    Windows/macOS/Linux

    极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。