Java基础之stream流最新版,stream流的基本操作

您好,我是码农飞哥(wei158556),感谢您阅读本文,欢迎一键三连哦
💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精通
😁 2. 毕业设计专栏,毕业季咱们不慌忙,几百款毕业设计等你选。
❤️ 3. Python爬虫专栏,系统性的学习爬虫的知识点。9.9元买不了吃亏,买不了上当 。python爬虫入门进阶
❤️ 4. Ceph实战,从原理到实战应有尽有。 Ceph实战
❤️ 5. Java高并发编程入门,打卡学习Java高并发。 Java高并发编程入门

文章目录

    • 1. Stream流是什么?
    • 2. Stream流的执行机制
      • 生成Stream流
      • 执行中间操作
      • 执行终止操作
    • 3.使用示例(中间操作)
      • 使用filter方法过滤所有红色苹果
      • 使用map方法,将所有苹果重量+10,并且输出对应的苹果的产地
      • sorted 排序方法
      • flatMap的使用
      • 去重,合并,跳过,截取(concat,distinct,skip,limit)
    • 终止操作
      • 聚合(max、min、count)
      • 统计(counting、averaging)
      • 遍历/匹配(foreach、find、match)
      • 归集collect(toList、toSet、toMap)
      • 分区、分组(partitioningBy、groupingBy)
      • 拼接(joining)

1. Stream流是什么?

JDK1.8 中增加了Stream流,Stream流是一种流式的处理数据的风格,也就是将要处理的数据当作流,在管道中进行传输,并在管道的每个节点对数据进行处理,如过滤、排序、转换等。

先来看一个Stream API的使用示例

       List<String> sourceList = Arrays.asList("1", "2", "", "12", "5");
        int sum = sourceList.stream()
                .filter(StringUtils::isNotBlank)
                .mapToInt(Integer::valueOf)
                .sum();
        System.out.println(sum);

这是个很简单的一个Stream使用例子,我们过滤掉空字符串后,转成int类型并对各个元素进行求和,这里有个三个操作:filter,mapToInt,sum。后面会详细介绍。

2. Stream流的执行机制

Stream内部通过流水线(Pipline)的方式来实现的,基本思路就是顺着流水线尽可能执行更多的操作,从而避免多次迭代。

Steam流操作有三个特性:

  1. Stream流不存储数据:而是按照特定的规则对数据进行计算,一般会输出结果。
  2. Stream流不改变源数据:通常情况下会产生一个新的集合或一个值。
  3. Stream流具有延迟执行特性:只有调用终端操作时,中间操作才会执行。

一个Stream流的使用主要包括三步:

Stream流执行机制

  1. 生成stream流:这就就是将输入的数据源转成Stream流,数据源主要是CollectionArray等集合数据。

  2. 执行中间操作:对数据进行处理

  3. 执行终止操作:返回最终的结果

    image-20230723160341372

生成Stream流

生成Stream流的方式有三种,分别是

List<String> sourceList = Arrays.asList("1", "2", "", "12", "5");
//1.创建stream串行流对象
sourceList.stream();
//2.创建可并行执行的stream流对象
sourceList.parallelStream();
//3.通过给定的一系列元素创建一个新的Stream串行流对象
Stream.of("12", "123", "14", "15");

执行中间操作

执行中间操作只是一种标记,只有结束操作才会触发实际计算。调用中间操作会返回一个新的流。 过滤,排序类的操作都是中间操作,中间操作可以有多个,中间操作分为无状态和有状态。

无状态:指元素的处理不受前面元素的影响。下面的方法均是无状态操作

方法说明
map()将已有元素转换为另一个对象类型,一对一逻辑
filter()按照条件过滤符号要求的元素
peek()对Stream流中的每个元素进行逐个遍历处理
unodered()返回一个无序的流,对于不关心顺序的数据处理和并行配合使用更佳。
mapToInt()将已有元素转成Int类型
mapToLong()将已有元素转成Long类型
mapToDouble()将已有元素转成Double类型
flatMap()将已有元素转换为另外对象类型,一对多逻辑
flatMapToInt()将已有元素转成Int类型

有状态:有状态的中间操作必须等所有元素处理之后才知道最终结果。比如排序是有状态的操作,在读取所有元素之前并不能确定排序结果。下面方法是有状态操作

方法说明
distinct()对stream中所有元素进行去重
sorted()结果排序
limit(n)仅保留集合前面指定个数的元素
skip(n)跳过集合前面指定个数的元素
concat()将两个流合并起来为1个新的流

执行终止操作

终止操作就是指定stream流的输出结果。

方法说明
count()元素个数
max()最大值
min()最小值
findFirst()第一个符合条件
findAny()任意一个符合条件
anyMatch()判断是否有符合条件元素
allMatch()是否所有元素都符合条件
noneMatch()是否所有元素都不符合
collect(Collectors进行指定)将流转换成指定类型
toArray()转换成数组
iterator()转换成iterator()对象
foreach()逐个遍历

3.使用示例(中间操作)

现在定义一个Apple类,此类有价格price,颜色color,重量weight,产地distinct 四个属性。

private static List<Apple> appleList = new ArrayList<>();

static {
    appleList.add(new Apple(10, "red", 12, "安徽"));
    appleList.add(new Apple(5, "red", 13, "江西"));
    appleList.add(new Apple(5, "blue", 10, "江西"));
    appleList.add(new Apple(40, "blue", 9, "河南"));
    appleList.add(new Apple(15, "blue", 11, "浙江"));
}
}
public class Apple {

    private Integer price;

    private String color;

    private Integer weight;

    private String district;

    public Apple(Integer price, String color, Integer weight, String district) {
        this.price = price;
        this.color = color;
        this.weight = weight;
        this.district = district;
    }
  省略getter和setter方法
}
  1. 使用filter方法过滤所有红色苹果

        //1.filter(过滤)筛选出所有颜色是红色的苹果
        List<Apple> red = appleList.stream().filter(apple -> apple.getColor().equals("red")).collect(Collectors.toList());
    
  2. 使用map方法,将所有苹果重量+10,并且输出对应的苹果的产地

        //2.map的使用,将所有苹果重量+10,并且输出对应的苹果的产地
    appleList.stream()
                    .map(apple -> {
                        apple.setWeight(apple.getWeight() + 10);
                        return apple;
                    }).map(Apple::getDistrict)
                    .collect(Collectors.toList());
    
  3. sorted 排序方法

    • sorted():自然排序,流中元素需实现Comparable接口
    • sorted(Comparator com):Comparator排序器自定义排序
 //3.sorted() 排序
        //按价格升序排序 自然排序
        System.out.println("按价格升序排序 自然排序");
        appleList.stream().sorted(Comparator.comparing(Apple::getPrice))
                .peek(System.out::println).collect(Collectors.toList());

        //按价格倒序排序 reversed()
        System.out.println("按价格倒序排序 reversed()");
        appleList.stream().sorted(Comparator.comparing(Apple::getPrice).reversed())
                .peek(System.out::println).collect(Collectors.toList());

        System.out.println("先按价格再按重量升序排序 thenComparing");
        //先按价格再按重量升序排序 thenComparing
        appleList.stream().sorted(Comparator.comparing(Apple::getPrice)
                        .thenComparing(Apple::getWeight))
                .peek(System.out::println)
                .collect(Collectors.toList());
        //自定义排序,先按价格再按重量(降序)
        System.out.println("自定义排序,先按价格再按年龄(降序)");
        appleList.stream().sorted((p1, p2) -> {
            if (p1.getPrice() == p2.getPrice()) {
                return p2.getWeight() - p1.getWeight();
            } else {
                return p2.getPrice() - p1.getPrice();
            }
        }).peek(System.out::println).collect(Collectors.toList());
  1. flatMap的使用

    • 当使用map()操作时,不是返回一个值,而是返回一个集合或者一个数组的时候,这时候就可以使用flatMap解决这个问题。就是扁平化将每个元素映射成另一个Stream对象。

    ,将两个字符数组合并成一个新的字符数组

      List<List<Integer>> lists = new ArrayList<>();
            List<Integer> list = new ArrayList<>();
            list.add(4444);
            list.add(33333);
            list.add(444444);
            lists.add(list);
            lists.stream().flatMap(Collection::stream).forEach(System.out::println);
    
            List<String> strings = Arrays.asList("m,k,l,a", "1,3,4,5");
            List<String> listNew = strings.stream().flatMap(s -> {
                //将每个元素转成一个新的stream
                String[] split = s.split(",");
                Stream<String> s2 = Arrays.stream(split);
                return s2;
            }).collect(Collectors.toList());
            System.out.println(listNew);
    
    
  2. 去重,合并,跳过,截取(concat,distinct,skip,limit)

    //创建两个流
    Stream<String> stream1 = Stream.of("1", "2", "", "12", "5");
    Stream<String> stream2 = Stream.of("3", "4", "5", "6");
    //concat:合并两个流    //distinct:去重
    List<String> lists1 = Stream.concat(stream1, stream2)
            .distinct().collect(Collectors.toList());
    //limit:限制从流中获取前n个数据
    List<String> collect = stream1.limit(3).collect(Collectors.toList());
    //skip:跳过前n个数据
    List<String> collect1 = stream1.skip(2).collect(Collectors.toList());
    

    终止操作

    1. 聚合(max、min、count)

      //取出价格最高的苹果
      appleList.stream().max(Comparator.comparing(Apple::getPrice)).get();
      //取出价格最低的苹果
      appleList.stream().min(Comparator.comparing(Apple::getPrice)).get();
      //统计元素个数
      appleList.stream().count();
      
    2. 统计(counting、averaging)

      Collectors提供了一系列用于数据统计的静态方法:

      • 计数:counting

      • 平均值:averagingInt、averagingLong、averagingDouble

      • 最值:maxBy、minBy

      • 求和:summingInt、summingLong、summingDouble

        //求平均重量
        Double avg = appleList.stream().collect(Collectors.averagingDouble(Apple::getWeight));
        //求和
        Integer sum = appleList.stream().collect(Collectors.summingInt(Apple::getWeight));
        
        //统计
        List<Integer> orgNums = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        IntSummaryStatistics statistics = orgNums.stream().mapToInt((x) -> x).summaryStatistics();
        System.out.println("列表中最大的数:" + statistics.getMax());
        System.out.println("列表中最小的数:" + statistics.getMin());
        System.out.println("所有数之和:" + statistics.getSum());
        System.out.println("平均数:" + statistics.getAverage());
        
    3. 遍历/匹配(foreach、find、match)

      //foreach
      appleList.stream().filter(apple -> apple.getColor().equals("blue"))
              .forEach(System.out::println);
      //匹配第一个颜色是blue的苹果
      appleList.stream().filter(apple -> apple.getColor().equals("blue"))
              .findFirst();
      //匹配任意一个颜色是blue的苹果
      appleList.stream().filter(apple -> apple.getColor().equals("blue"))
              .findAny();
      //是否包含符合特定条件的元素
      appleList.stream().anyMatch(apple -> apple.getColor().equals("blue"));
      
    4. 归集collect(toList、toSet、toMap)

      appleList.stream().map(Apple::getDistrict).collect(Collectors.toList());
      //调用toMap方法时,如果key重复可以如下处理
      Map<String, Apple> collect = appleList.stream().collect(Collectors.toMap(Apple::getDistrict, a->a,(a1,a2)->a1));
      //集合去重
      Set<Apple> collect1 = appleList.stream().collect(Collectors.toSet());
      
    5. 分区、分组(partitioningBy、groupingBy)

      • 分区:将stream按条件分为两个Map,比如水果按照价格是否高于12分出两部分。

      • 分组:将集合分为多个Map,比如水果按产地分组。有单级分组和多级分组。

        //- 分区:将stream按条件分为两个Map,比如水果按照价格是否高于12分出两部分。
        Map<Boolean, List<Apple>> collect = appleList.stream().collect(Collectors.partitioningBy(apple -> apple.getPrice() > 12));
        //- 分组:将集合分为多个Map,比如水果按产地分组。有单级分组和多级分组。
        Map<String, List<Apple>> collect1 = appleList.stream().collect(Collectors.groupingBy(apple -> apple.getDistrict()));
        
    6. 拼接(joining)

      List<String> list = Arrays.asList("1","2","3","4");
      //以空字符拼接,输出 1234
      String result= list.stream().collect(Collectors.joining());
      //以“-”符号拼接,输出1-2-3-4
      String result1= list.stream().collect(Collectors.joining("-"));
      System.out.println(result1);
      

多个参数

joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) 方法接受一个字符串序列作为拼接符,并在拼接完成后添加传递的前缀和后缀。假如我们传递的分隔符为 “-”,前缀为 “[” , 后缀为 “]” 。那么输出结果为 [1-2-3-4]

    List<String> arrayList = Arrays.asList("1","2","3","4");
        String collect = arrayList.stream().collect(Collectors.joining(",", "[", "]"));

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

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

相关文章

vue实现仿手写稿样式,可导出成png图片

文章目录 环境实现效果代码 环境 安装html2canvas&#xff0c;用于将指定标签下的全部子节点转换为图片 npm install html2canvas实现 <template><div class"handwrite"><div id"left" class"left"><div id"backImg…

C++ | set与map的用法指南

前言 前面我们学习了vector、list等容器&#xff0c;其实他们都属于序列式容器&#xff0c;因为其底层为线性结构&#xff1b;今天我们学习使用的set与map是属于关联式容器&#xff0c;关联式容器更注重于数据检索访问的效率&#xff1b;本文所有的资料均查阅于文档&#xff0c…

RocketMQ深入分析

RocketMQ深入分析 1. 消息存储 目前的MQ中间件从存储模型来&#xff0c;分为需要持久化和不需要持久化的两种模型&#xff0c;现在大多数的是支持持久化存储的&#xff0c;比如ActiveMQ、RabbitMQ、Kafka、RocketMQ&#xff0c;ZeroMQ却不需要支持持久化存储而业务系统也大多…

BART模型和 Electra模型对比

总结 Electra模型在使用较少的计算资源的情况下能够达到跟大语言模型相近的效果。但BART模型对于传统的BERT中加入了不同种制造noise的方式&#xff0c;是BERT和GPT的结合体。Electra模型主要是Generator模型和Discriminator模型的结合体。 未知参数设置&#xff0c;两个模型…

【历史上的今天】7 月 20 日:人类登上月球;数据仓库之父诞生;Mac OS X Lion 发布

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 7 月 20 日&#xff0c;在 2005 年的今天&#xff0c;时任微软全球副总裁的李开复加盟谷歌担任谷歌全球副总裁及中国区总裁。谷歌公司在发布聘请李开复消息的同…

Rust之通用编程

1、变量与可变性&#xff1a; 在Rust语言中&#xff0c;变量默认是不可变的&#xff0c;所以一旦变量被绑定到某个值上面&#xff0c;这个值就再也无法被改变。 可以通过在声明的变量名称前添加mut关键字来使其可变。除了使变量的值可变&#xff0c;mut还会向阅读代码的人暗示…

【机器学习】分类算法 - KNN算法(K-近邻算法)KNeighborsClassifier

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;零基础快速入门人工智能《机器学习入门到精通》 K-近邻算法 1、什么是K-近邻算法&#xff1f;2、K-近邻算法API3、…

【论文阅读 03】机器学习算法在颈动脉斑块影像学分类中的研究进展

读完之后就是&#xff0c;总结 机器学习&#xff08;SVM、小波&#xff09;和深度学习&#xff08;CNN&#xff09;在 颈动脉斑块影像学中的 分类效果。只讨论了超声、磁共振两种成像 Chin J Clin Neurosci 临床神经科学杂志 复旦大学 颈动脉斑块( carotid plaques) 是一种…

opencv 之 外接多边形(矩形、圆、三角形、椭圆、多边形)使用详解

opencv 之 外接多边形&#xff08;矩形、圆、三角形、椭圆、多边形&#xff09;使用详解 本文主要讲述opencv中的外接多边形的使用&#xff1a; 多边形近似外接矩形、最小外接矩形最小外接圆外接三角形椭圆拟合凸包 将重点讲述最小外接矩形的使用 1. API介绍 #多边形近似 v…

若依微服务整合activiti7.1.0.M6

若依微服务3.6.3版本整合activiti7&#xff08;7.1.0.M6&#xff09; 目前有两种办法集成activiti7 放弃activiti7新版本封装的API&#xff0c;使用老版本的API&#xff0c;这种方式只需要直接集成即可&#xff0c;在7.1.0.M6版本中甚至不需要去除security的依赖。不多介绍&a…

Origin科学绘图分析软件2023最新版下载安装教程

在科学研究和工程领域&#xff0c;数据的处理和分析是至关重要的一环&#xff0c;而Origin则是这方面的一款重要工具。Origin软件是由OriginLab公司开发的&#xff0c;主要用于各种科学数据的处理和分析&#xff0c;以及高质量的科学图形的创建。#乐享周末分享吧# 下载地址文末…

【英杰送书第三期】Spring 解决依赖版本不一致报错 | 文末送书

Yan-英杰的主 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 问题描述 报错信息如下 报错描述 解决方法 总结 【粉丝福利】 【文末送书】 目录&#xff1a; 本书特色&#xff1a; 问题描述 报错信息如下 Description:An attempt…

微服务保护——Sentinel【实战篇二】

一、线程隔离 &#x1f349; 线程隔离有两种方式实现&#xff1a; 线程池隔离信号量隔离&#xff08;Sentinel默认采用&#xff09; 线程隔离&#xff08;舱壁模式&#xff09;&#x1f95d; 在添加限流规则时&#xff0c;可以选择两种阈值类型&#xff1a; QPS&#xff1a;…

Java反射 -- 详细介绍 (框架核心)

反射 是 Java框架 的核心 &#xff0c;无论是Tomcat、SpringMVC、Spring IOC、Spring AOP、动态代理 &#xff0c;都使用到了 反射 反射的作用简单讲就是 无需 new 对象&#xff0c;就可以动态获取到一个类的全部信息&#xff0c;包括 属性、方法&#xff0c;构造器&#xff0…

3、C# 方法构成

上一节,我们讲述了程序的基本构成。由大到小分别为”解决方案-->项目-->类-->方法“。 这一节,我们讲讲方法。 方法可以说是程序的基本构成单位。假如把方法抽象成点的话,我们可以认为程序是一个树状的结构。树根,就是我们的起点方法,也叫主方法。这一点,基本…

iOS 测试 iOS 端 Monkey 测试

说起 Monkey 测试&#xff0c;大家想到的是 monkey 测试只有安卓有&#xff0c;monkey 测试只针对安卓 app&#xff0c;今天给大家分享一下 Monkey 测试在 iOS 端也能跑&#xff01;iOS 端 app 也能使用 Monkey 测试来执行稳定性测试。 一、环境准备 1、准备 Mac 设备&#x…

SpringCloud分布式项目下feign的使用

新建一个feign的微服务&#xff08;后面统称为A&#xff09;&#xff0c;其他项目要使用利用maven导入该服务模块的依赖就行了 导入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</…

Tabby - 本地化AI代码自动补全 - Linux Debian

参考&#xff1a; https://github.com/TabbyML/tabby Docker | Tabby Linux Debian上快速安装Docker并运行_Entropy-Go的博客-CSDN博客 Tabby - 本地化AI代码自动补全 - Windows10_Entropy-Go的博客-CSDN博客 为什么选择Tabby 已经有好几款类似强劲的代码补全工具&#xf…

【苹果日历推送】群发部署开发工具、SDK或框架,如APNs推送服务的HTTP/2接口

苹果日历本身并不直接支持群发推送通知&#xff0c;因为推送通知是针对单个设备的。如果你想向多个用户发送推送通知&#xff0c;你需要在自己的应用中实现推送功能&#xff0c;然后针对每个设备单独发送推送通知。 以下是实现推送通知的一般步骤&#xff1a; 开发推送服务&a…

【Linux | Shell】结构化命令2 - test命令、方括号测试条件、case命令

目录 一、概述二、test 命令2.1 test 命令2.2 方括号测试条件2.3 test 命令和测试条件可以判断的 3 类条件2.3.1 数值比较2.3.2 字符串比较 三、复合条件测试四、if-then 的高级特性五、case 命令 一、概述 上篇文章介绍了 if 语句相关知识。但 if 语句只能执行命令&#xff0c…