Java8新特性---Stream流

news2024/10/6 0:34:22

什么是Stream

  • 是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
  • 集合讲究的是数据,流讲的是计算

注意:

  • Stream不会自己存储元素
  • Stream不会改变源对象,相反,他们会返回持有结果的新的Stream
  • Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Stream操作步骤

请添加图片描述
对于一个数据源,我们先获取一个流,然后对这些流进行处理,包括筛选、切片、映射、排序等,最后还需要一个终止操作,包括查找匹配、找最大、最小值、迭代、计算、规约等。

  • 在这个过程中就,有几点需要注意,首先数据源是没有发生变化的,所做的处理都是对于流,源数据源不变。第二,它是延迟执行的,也就是如果没有终止操作,那么无论做什么中间操作,它都是不做任何处理,没有变化的,只有出现了终止操作,才会进行处理。同时,终止操作也只能有一个,有了终止操作后就不能再对流进行操作。

  • 1、创建Stream
    一个数据源(如:集合、数组),获取一个流

  • 2、中间操作
    一个中间操作链,对数据源的数据进行处理

  • 3、终止操作
    一个终止操作,执行中间操作链,并产生结果

创建Stream流

Java8 中的 Collection 接口被扩展,提供了两个获取流的方法:

  • default Stream stream() : 返回一个顺序流

  • default Stream parallelStream() : 返回一个并行流

由数组创建流

  • static Stream stream(T[] array): 返回一个流
  • 重载形式,能够处理对应基本类型的数组:
    ⚫ public static IntStream stream(int[] array)
    ⚫ public static LongStream stream(long[] array)
    ⚫ public static DoubleStream stream(double[] array)

由值创建流

  • 可以使用静态方法 Stream.of(), 通过显示值创建一个流。它可以接收任意数量的参数。
  • ⚫ public static Stream of(T… values) : 返回一个流

由函数创建流:创建无限流

  • 可以使用静态方法 Stream.iterate() 和Stream.generate(), 创建无限流。
  • ⚫ 迭代 public static Stream iterate(final T seed, final UnaryOperator f)
  • ⚫ 生成 public static Stream generate(Supplier s)
@Test
    public void test1(){
        //通过Collection 系列集合提供的stream()或parallelStream()
        ArrayList<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();
        //通过Arrays中的静态方法stream()获取数组流
        Employee[] employees = new Employee[10];
        Stream<Employee> stream2 = Arrays.stream(employees);

        //通过Stream类中的静态方法of()
        Stream<String> stream3 = Stream.of("aa", "bb", "cc");

        //创建无限流
        //迭代
        Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);
        stream4.limit(22)
                .forEach(System.out::println);

        //生成
        Stream<Double> stream5 = Stream.generate(() -> Math.random());
    }

Stream的中间操作

  • 多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。

筛选与切片

在这里插入图片描述

List<Employee> emps = Arrays.asList(
            new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),
            new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
            new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
            new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
            new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
            new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
            new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
    );
    @Test
    public void test2(){
        Stream<Employee> stream = emps.stream()
                .filter((e) -> {
                    System.out.println("Stream中间操作");
                    return e.getAge() > 35;
                });

        //终止操作
        stream.forEach(System.out::println);
    }

    @Test
    public void test3(){
        emps.stream()
                .filter((e)->e.getSalary()>5000)
                .limit(2)
                .forEach(System.out::println);
    }
    @Test
    public void test4(){
        emps.stream()
                .filter((e)->e.getSalary()>5000)
                .skip(2)
                .distinct()
                .forEach(System.out::println);
    }

映射

在这里插入图片描述

 @Test
    public void test5(){
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");

        list.stream()
                .map((str)->str.toUpperCase())
                .forEach(System.out::println);

        System.out.println("--------------------");

        //应用,获取一个集合中的某种属性的集合
        emps.stream()
                .map(Employee::getName)
                .forEach(System.out::println);

        System.out.println("--------------------");


        Stream<Stream<Character>> stream = list.stream()
                .map(StreamTest1::filterCharacter); //{{a,a,a},{b,b,b}...}
        stream.forEach((sm)->{
            sm.forEach(System.out::println);
        });

        System.out.println("--------------------");

        Stream<Character> characterStream = list.stream()
                .flatMap(StreamTest1::filterCharacter);//{a,a,a,b,b,b...}
        characterStream.forEach(System.out::println);
    }

    public static Stream<Character> filterCharacter(String str){
        List<Character> list =new ArrayList<>();
        for(Character ch:str.toCharArray()){
            list.add(ch);
        }
        return list.stream();
    }

排序

在这里插入图片描述

 @Test
    public void test6(){
        List<String> list = Arrays.asList("ccc", "aaa", "bbb", "ddd", "eee");
        list.stream()
                .sorted()
                .forEach(System.out::println);
        System.out.println("--------------------");
        emps.stream()
                .sorted((e1,e2)->{
                    if(e1.getAge()==e2.getAge()){
                        return e1.getId()-e2.getId();
                    }else{
                        return e1.getAge()-e2.getAge();
                    }
                }).forEach(System.out::println);
    }

Stream的终止操作

  • 终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。
  • 使用终止操作后,流不能再操作

查找与匹配

在这里插入图片描述

 @Test
    public void test7(){
        boolean b1 = emps.stream()
                .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b1);

        boolean b2 = emps.stream()
                .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b2);

        boolean b3 = emps.stream()
                .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b3);

        Optional<Employee> op1 = emps.stream()
                .sorted(Comparator.comparingDouble(Employee::getSalary))
                .findFirst();
        System.out.println(op1.get());

        Optional<Employee> op2 = emps.stream()
                .filter((e)->e.getStatus().equals(Employee.Status.BUSY))
                .findAny();
        System.out.println(op2.get());

    }

计算、求最值、迭代

在这里插入图片描述

@Test
    public void test8(){
        long count = emps.stream()
                .count();
        System.out.println(count);

        Optional<Employee> optional1 = emps.stream()
                .max(Comparator.comparingDouble(Employee::getSalary));
        System.out.println(optional1.get());

        Optional<Double> optional2 = emps.stream()
                .map(Employee::getSalary)
                .min(Double::compare);
        System.out.println(optional2.get());
    }

归约

在这里插入图片描述

  • map 和 reduce 的连接通常称为map-reduce 模式,因 Google 用它来进行网络搜索而出名。
@Test
    public void test9(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum = list.stream()
                .reduce(1, (x, y) -> x + y);//从1开始做x+y操作 -> 1+1+2+....+10
        System.out.println(sum);


        System.out.println("----------------------");

        Optional<Double> op = emps.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);
        System.out.println(op.get());

    }

收集

在这里插入图片描述

  • Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:
    在这里插入图片描述
    在这里插入图片描述
public class StreamTest2 {

    List<Employee> emps = Arrays.asList(
            new Employee(102, "李四", 79, 6666.66, Employee.Status.BUSY),
            new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
            new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
            new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
            new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
            new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
            new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
    );
    @Test
    public void test3(){
        List<String> list = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());

        list.forEach(System.out::println);

        System.out.println("----------------------------------");

        Set<String> set = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet());

        set.forEach(System.out::println);

        System.out.println("----------------------------------");

        HashSet<String> hs = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));

        hs.forEach(System.out::println);
    }

    @Test
    public void test4(){
        Optional<Double> max = emps.stream()
                .map(Employee::getSalary)
                .collect(Collectors.maxBy(Double::compare));

        System.out.println(max.get());

        Optional<Employee> op = emps.stream()
                .collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));

        System.out.println(op.get());

        Double sum = emps.stream()
                .collect(Collectors.summingDouble(Employee::getSalary));

        System.out.println(sum);

        Double avg = emps.stream()
                .collect(Collectors.averagingDouble(Employee::getSalary));

        System.out.println(avg);

        Long count = emps.stream()
                .collect(Collectors.counting());

        System.out.println(count);

        System.out.println("--------------------------------------------");

        DoubleSummaryStatistics dss = emps.stream()
                .collect(Collectors.summarizingDouble(Employee::getSalary));

        System.out.println(dss.getMax());
    }

    //分组
    @Test
    public void test5(){
        Map<Employee.Status, List<Employee>> map = emps.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));

        System.out.println(map);
    }

    //多级分组
    @Test
    public void test6(){
        Map<Employee.Status, Map<String, List<Employee>>> map = emps.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
                    if (e.getAge() >= 60)
                        return "老年";
                    else if (e.getAge() >= 35)
                        return "中年";
                    else
                        return "成年";
                })));

        System.out.println(map);
    }

    //分区
    @Test
    public void test7(){
        Map<Boolean, List<Employee>> map = emps.stream()
                .collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));

        System.out.println(map);
    }

    //
    @Test
    public void test8(){
        String str = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.joining("," , "----", "----"));

        System.out.println(str);
    }

    @Test
    public void test9(){
        Optional<Double> sum = emps.stream()
                .map(Employee::getSalary)
                .collect(Collectors.reducing(Double::sum));

        System.out.println(sum.get());
    }
}

并行流和串行流

  • 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
  • Java 8 中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API 可以声明性地通过 parallel()sequential() 在并行流与顺序流之间进行切换。

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

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

相关文章

GPT-4耗尽全宇宙数据!OpenAI接连吃官司,竟因数据太缺了,UC伯克利教授发出警告

穷尽「全网」&#xff0c;生成式AI很快无数据可用。 近日&#xff0c;著名UC伯克利计算机科学家Stuart Russell称&#xff0c;ChatGPT和其他AI工具的训练可能很快耗尽「全宇宙的文本」。 换句话说&#xff0c;训练像ChatGPT这样的AI&#xff0c;将因数据量不够而受阻。 这可能…

五、修改官方FreeRTOS例程(STM32F1)

1、官方源码下载 (1)进入FreeRTOS官网&#xff1a;FreeRTOS官网 (2)下载FreeRTOS。(选择带示例的下载) 2、删减目录 (1)下载后解压的FreeRTOS文件如下图所示。 (2)删除下图中红框勾选的文件。 FreeRTOS-Plus&#xff0c;FreeRTOS的生态文件&#xff0c;非必需的。tools&…

esp8266+电压检测模块检测电池电压

该模块5v时输出1v&#xff0c;因esp8266 ADC引脚(A0)支持电压范围是0v-1v&#xff0c;所以该方案仅支持0-5v电压检测 接线&#xff1a; - 接 esp8266GND 可不接 S 接 ADC esp8266 为 A0 VCC 被检测直流电 GND 被检测直流电- #include <Wire.h>const int adcPin A0; // …

Redis五大基本数据类型及其使用场景

文章目录 **一 什么是NoSQL&#xff1f;****二 redis是什么&#xff1f;****三 redis五大基本类型**1 String&#xff08;字符串&#xff09;**应用场景** 2 List&#xff08;列表&#xff09;**应用场景** 3 Set&#xff08;集合&#xff09;4 sorted set&#xff08;有序集合…

excel逻辑函数篇1

1、AND(logical1,[logical2],…)&#xff1a;用于测试所有条件是否均为TRUE 检查所有参数均为true&#xff0c;如果是则返回true 2、OR(logical1,[logical2],…)&#xff1a;用于测试是否有为TRUE的条件 如果任意参数值为true&#xff0c;即返回true&#xff1b;只有当所有参数…

223、仿真-基于51单片机温湿度PH值二氧化碳(C02)报警Proteus仿真设计(程序+Proteus仿真+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 四、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选择 方案一&…

机器学习笔记 - 基于keras + 小型Xception网络进行图像分类

一、简述 Xception 是深度为 71 层的卷积神经网络,仅依赖于深度可分离的卷积层。 论文中将卷积神经网络中的 Inception 模块解释为常规卷积和深度可分离卷积运算(深度卷积后跟点卷积)之间的中间步骤。从这个角度来看,深度可分离卷积可以理解为具有最大数量塔的 Inception 模…

学习笔记230804---restful风格的接口,delete的传参方式问题

如果后端提供的删除接口是restful风格&#xff0c;那么使用地址栏拼接的方式发送请求&#xff0c;数据放在主体中&#xff0c;后端接受不到&#xff0c;当然也还有一种可能&#xff0c;后端在这个接口的接参设置上是req.query接参。 问题描述 今天遇到的问题是&#xff0c;de…

windows子系统wsl2备份(迁移D盘)还原系统

windows子系统wsl2备份还原系统 1.查看wsl版本 wsl -l -v2.停止wsl子系统 wsl --terminate Ubuntu-22.043.导出子系统备份 wsl --export Ubuntu-22.04 D:\Ubuntu_bak.tar4.删除原有系统 wsl --unregister Ubuntu-22.045.还原系统 wsl --import Ubuntu-22.04 d:\Ubuntu-ws…

Jenkins-发送邮件配置

在Jenkins构建执行完毕后&#xff0c;需要及时通知相关人员。因此在jenkins中是可以通过邮件通知的。 一、Jenkins自带的邮件通知功能 找到manage Jenkins->Configure System&#xff0c;进行邮件配置&#xff1a; 2. 配置Jenkins自带的邮箱信息 完成上面的配置后&#xf…

【0基础入门Python笔记】三、python 之函数以及常用内置函数

三、python 之函数以及常用内置函数 函数函数定义函数调用函数参数返回值 常用内置函数input()函数range()函数其它 函数 函数是一种用于封装可重复使用代码块的工具&#xff0c;能够将一系列操作组织成一个逻辑单元。 函数定义 在Python中&#xff0c;函数通过def关键字进行…

Python可视化在量化交易中的应用(12)_Seaborn柱状图

Seaborn中柱状图的绘制方法 seaborn中绘制折线图使用的是sns.barplot()函数&#xff1a; sns.barplot(x,y,hue,data,order,hue_order,estimator,ci95,n_boot1000,units,seed,orient,color,palette,saturation0.75,errcolor‘.26’,errwidth,capsize,dodgeTrue,ax,**kwargs,) …

linux RabbitMQ-3.8.5 安装

软件版本操作系统CentOS Linux release 7.9.2009erlangerlang-23.0.2-1.el7.x86_64rabbitMQrabbitmq-server-3.8.5-1.el7 RabbitMQ的安装首先需要安装Erlang,因为它是基于Erlang的VM运行的。 RabbitMQ安装需要依赖:socat和logrotate&#xff0c;logrotate操作系统已经存在了&…

内网穿透技术之神卓互联如何检测本地环境

在使用神卓互联Windows版客户端的过程中添加和编辑映射通道默认会自动生效&#xff0c;如您遇到无法访问的情况&#xff0c;可通过客户端上的检测工具进行环境检测。 Windows客户端检测本地环境&#xff0c;登录神卓互联客户端&#xff0c;在主界面下方的按钮组里选择【环境检…

《Python入门到精通》os模块详解,Python os标准库

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 os模块详解 1、文件目录操作os.stat() 获取文件状态os.utime() 修改文件时间os.r…

PostgreSQL父子建表查询所有的子数据-利用自定义函数查询

pgsql 函数查询代码 select find_space_tree_list_by_nodeid(1,1) 查询结果示意图 获取子集函数代码 CREATE OR REPLACE FUNCTION "public"."find_space_tree_list_by_nodeid"("nodeid" varchar, "viewid" varchar)RETURNS "…

8.19论文阅读

文章目录 Graph-Segmenter: Graph Transformer with Boundary-aware Attention for Semantic Segmentation方法 SCSC: Spatial Cross-scale Convolution Module to Strengthen both CNNs and Transformers方法 Deformable Mixer Transformer with Gating for Multi-Task Learni…

KFC玩具HelloKitty风扇改造——ESP32蓝牙blinker、1404无刷电机、双18650

改装KFC玩具——ESP32蓝牙无刷风扇 ESP32代码&#xff1a; 使用NodeMCU-32S #define BLINKER_BLE#include <Blinker.h>#include <Arduino.h>// PWM通道 int channel_PWM 3; // PWM频率&#xff0c;那么周期也就是1/50&#xff0c;也就是20ms &#xff0c;PWM一…

2.创建小程序

创建 在开发工具中,选择小程序,点击加号 填写小程序信息,模板使用的是TS+Sass 编辑器的工作区 目录结构 项目使用的是ts的模板,目录结构和js的有一点差异,目录结构如下: miniprogram:小程序根目录 —pages:小程序页面目录 ——xxx:页面目录,一个页面对应一个目…

加了一个班,简单2步就设置好了公司的内网穿透服务

单位里没有固定的网管&#xff0c;胆子全落在我的身上。 起初是最近买了一套客户及财务软件&#xff0c;其实专业术语就是ERP&#xff0c;主管让我们把手头的资料全部录入进去&#xff0c;说是可以提高我们的工作效率&#xff0c;于是我们就开始各种录入&#xff0c;那个时候已…