• 不会吧,都2023年了你还不会JavaStream?


    ✨这里是第七人格的博客✨小七,欢迎您的到来~✨

    🍅系列专栏:无🍅

    ✈️本篇内容: Java Stream✈️

    🍱本篇收录完整代码地址:无🍱

    楔子

    仅以此篇献给曾经被Stream流惊艳到的自己,和爱好学习的你。

    Java Stream和集合的区别

    Stream流和集合在Java中的主要区别如下:

    1. 数据结构:Stream流不是数据结构,而是一种处理数据的抽象概念。它不存储元素,而是通过计算操作管道传递来自源的元素。集合是一种传统的数据结构,用于存储和操作一组对象。

    2. 处理方式:Stream流允许以声明性方式处理数据集合,可以通过链式调用一系列的操作来处理数据。集合提供了丰富的方法来查询和操作数据,如添加、删除、修改元素等。

    3. 并行处理:Stream流支持并行处理,可以充分利用多核处理器的优势来提高处理速度。集合不支持并行处理。

    4. 延迟计算:Stream流支持延迟计算,只有在需要时才会计算结果。这样可以节省内存和计算资源。集合在创建时就分配了内存空间,无法实现延迟计算。

    5. 可读性:Stream流的操作更加声明式,易于阅读和理解。集合的操作相对繁琐,可读性较差。

    Java Stream的组成

    Java Stream 由三部分组成:Stream Source(流源)、Stream Processing(流处理)和 Stream Sink(流接收器)。

    1. Stream Source(流源):Stream Source 是数据的来源,可以是集合、数组、I/O 通道等。Stream Source 提供了一种抽象的接口,使得我们可以方便地从多个数据源中获取数据。

    2. Stream Processing(流处理):Stream Processing 是对 Stream Source 中的数据进行操作的过程。在 Java 8 中,Stream Processing 是通过 Stream API 来实现的,它提供了一系列的中间操作和终端操作,可以对数据进行过滤、映射、排序等操作。

    3. Stream Sink(流接收器):Stream Sink 是将 Stream Processing 的结果输出到某个目的地的接口。在 Java 8 中,Stream Sink 可以是文件、数据库、网络连接等,也可以是其他数据结构,如集合或数组。通过 Stream Sink,我们可以将流处理的结果保存到磁盘、数据库或其他存储设备中。

    Java Stream的操作分类

    请添加图片描述

    1、中间操作不会立即执行,而是返回一个新的流,这个新的流可以被进一步处理或收集到结果容器中。

    2、终端操作会触发实际的计算和输出,将结果返回给调用方。

    Java Stream的使用例子

    首先创建基础演示类,包含演示对象Student

    public class StreamOperator {
    
        List<Student> list = Student.createStudentList();
    
        public static class Student {
            private String name;
            private Integer age;
    
            private String address;
    
            public Student(String name, Integer age, String address) {
                this.name = name;
                this.age = age;
                this.address = address;
            }
    
            public String getAddress() {
                return address;
            }
    
            public void setAddress(String address) {
                this.address = address;
            }
    
            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;
            }
    
            static List<Student> createStudentList() {
                return Arrays.asList(
                        new Student("第七人格", 18, "www.52javaee.com"),
                        new Student("张三", 18, "北京"),
                        new Student("李四", 19, "上海"),
                        new Student("王五", 20, "深圳"),
                        new Student("赵六", 21, "广州"),
                        new Student("田七", 22, "杭州")
                );
            }
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    peek

    对流中元素进行遍历操作

    @Test
    public void peek() {
        list.stream()
                .peek(student -> System.out.println(student.getName()))
                .forEach(item -> System.out.println(JSON.toJSONString(item, true)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    filter

    过滤掉不符合断言判断的数据

    @Test
    public void filterTest() {
        list.stream()
                .filter(student -> "第七人格".equals(student.getName()))
                .forEach(item -> System.out.println(JSON.toJSONString(item, true)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    顺便提一下,filter方法参数声明如下(结合上一章我们学过的Lamda表达式,你get到了吗?)

    Stream<T> filter(Predicate<? super T> predicate);
    
    • 1

    map

    将一个元素转换成另一个元素

    @Test
    public void mapTest() {
        list.stream()
                .map(Student::getName)
                .forEach(item -> System.out.println(JSON.toJSONString(item, true)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    flatMap

    将一个对象转换成流

    @Test
    public void flatMapTest() {
        list.stream()
                .flatMap(student -> Arrays.stream(student.getName().split("")))
                .forEach(item -> System.out.println(JSON.toJSONString(item, true)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    sort

    对流中元素进行排序

    @Test
    public void sortTest() {
        list.stream()
                .peek(student -> System.out.println(student.getName()))
                .sorted(Comparator.comparing(Student::getAge))
                .forEach(item -> System.out.println(JSON.toJSONString(item, true)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    skip

    跳过前几条记录

    @Test
    public void skipTest() {
        list.stream()
                .sorted(Comparator.comparing(Student::getAge))
                .skip(5)
                .forEach(item -> System.out.println(JSON.toJSONString(item, true)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    limit

    截断前N条记录

    @Test
    public void limitTest() {
        list.stream()
                .sorted(Comparator.comparing(Student::getAge))
                .skip(2)
                .limit(3)
                .forEach(item -> System.out.println(JSON.toJSONString(item, true)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    distinct

    对流元素进行去重

    @Test
    public void distinctTest() {
        list.stream()
                .map(Student::getAge)
                .distinct()
                .forEach(item -> System.out.println(JSON.toJSONString(item, true)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    allMatch

    必须所有元素匹配,才返回true

    @Test
    public void allMatchTest() {
        boolean match = list.stream()
                .peek(student -> System.out.println(student.getName()))
                .allMatch(student -> student.getAge() > 18);
    
        System.out.println(match);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    anyMatch

    只要有任意一个元素匹配,就返回true

    @Test
    public void anyMatchTest() {
        boolean match = list.stream()
                .peek(student -> System.out.println(student.getName()))
                .anyMatch(student -> student.getAge() > 18);
    
        System.out.println(match);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    noneMatch

    所有元素都不匹配,才返回true

    @Test
    public void noneMatchTest() {
        boolean match = list.stream()
                .peek(student -> System.out.println(student.getName()))
                .noneMatch(student -> student.getAge() > 18);
        
        System.out.println(match);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    findFirst

    获取第一个元素

    @Test
    public void findFirstTest() {
        Optional<Student> optional = list.stream()
                .peek(student -> System.out.println(student.getName()))
                .findFirst();
    
        System.out.println(JSON.toJSONString(optional.get(), true));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    findAny

    获取任意一个元素

    @Test
    public void findAnyTest() {
        Optional<Student> optional = list.stream()
                .peek(student -> System.out.println(student.getName()))
                .findAny();
    
        System.out.println(JSON.toJSONString(optional.get(), true));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    max

    获取最大值

    @Test
    public void maxTest() {
        OptionalDouble optionalDouble = list.stream()
                .mapToDouble(Student::getAge)
                .max();
    
        System.out.println(optionalDouble.getAsDouble());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    min

    获取最小值

    @Test
    public void minTest() {
        OptionalDouble optionalDouble = list.stream()
                .mapToDouble(Student::getAge)
                .min();
    
        System.out.println(optionalDouble.getAsDouble());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    count

    获取条数

    @Test
    public void countTest() {
        long count = list.stream().count();
    
        System.out.println(count);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    总结

    本文主要介绍了Java Stream的一些基本概念和常见使用例子。方便新手学习,和老手查找巩固。

    下章预告

    Java Stream 收集器

  • 相关阅读:
    25种ACM模式输入输出模板,支持C++、Java、Python、Go、JS版本
    嵌入式开发学习之--创建工程
    关于黑马hive课程案例FineBI中文乱码的解决
    【甄选靶场】Vulnhub百个项目渗透——项目十五:Raven-1(wp利用,UDF提权)
    zk客户端连接关闭服务端,查看znode(重补早期的学习记录)
    调研:huggingface-diffusers
    Visual Studio 2022导入OpenCv库(配置项目属性表,可复用)
    springboot+学校运动会信息管理 毕业设计-附源码231058
    融云「百幄」之数字人,升级交互体验的「新同事」
    JavaScript常用事件详解
  • 原文地址:https://blog.csdn.net/a18602320276/article/details/132899876