每天学一点之Stream流相关操作

news2024/10/7 8:27:38

StreamAPI

一、Stream特点

Stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,负责存储数据,Stream流讲的是计算,负责处理数据!”

注意:

①Stream 自己不会存储元素。
②Stream 不会改变源对象。每次处理都会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

二、Stream操作的步骤

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

2- 中间操作:每次处理都会返回一个持有结果的新Stream,即中间操作的方法返回值仍然是Stream类型的对象,因此中间操作可以是个操作链(返回值类型是Stream类型的可以一直使用.方法操作),可对数据源的数据进行n次处理,但是在终结操作前,并不会真正执行。

3- 终止操作:终止操作的方法返回值类型就不再是Stream了,因此一旦执行终止操作,就结束整个Stream操作了。一旦执行终止操作,就执行中间操作链,最终产生结果并结束Stream。

在这里插入图片描述

案例分析:

 @Test
    public void test1(){
        //1、创建Stream,指定数据源来创建Stream
        ArrayList<String> list = new ArrayList<>();
        list.add("hello");
        list.add("java");
        list.add("hi");
        list.add("heihei");
        Stream<String> stream = list.stream();

        //2、加工处理
        //假设我要处理的要求:把里面所有的e字母,修改为a
        //Function<T,R> 的抽象方法  R apply(T t)
        stream = stream.map(s-> s.replace('e','a'));
        //假设我要处理的要求:筛选出包含a字母的单词
        //Predicate<T>接口   boolean test(T t)
        stream = stream.filter(s -> s.contains("a"));
        //处理,打印所有包含"a"字母的单词
        //Consumer<T> 的抽象方法  void accept(T t)
        stream = stream.peek( s -> System.out.println(s));
        
        //3、结束处理
        //统计满足条件的单词的个数
//         long count = stream.count();//没有这一步,前面的加工处理不执行
//        System.out.println("count = " + count);

        System.out.println("list = " + list);//不会修改数据源
    }

没有开启3、结束处理步骤时的运行结果:
在这里插入图片描述

开启之后的运行结果:

在这里插入图片描述

三、创建StreamAPI

1、创建 Stream方式一:通过集合

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

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

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

Stream stream = list.stream();

2、创建 Stream方式二:通过数组

Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:

  • public static Stream stream(T[] array): 返回一个流

String[] arr = {“hello”,“world”,“java”};
Stream stream = Arrays.stream(arr);

3、创建 Stream方式三:通过Stream的of()

可以调用Stream类静态方法 of(), 通过显示值创建一个流。它可以接收任意数量的参数。

  • public static Stream of(T… values) : 返回一个顺序流

Stream stringStream = Stream.of(“hello”, “world”, “java”);

4、创建 Stream方式四:创建无限流

可以使用静态方法 Stream.iterate() 和 Stream.generate(), 创建无限流。

  • public static Stream iterate(final T seed, final UnaryOperator f):返回一个无限流
  • public static Stream generate(Supplier s) :返回一个无限流
@Test
    public void test4(){
        //Supplier<T> 的抽象方法  T get()
        Stream<Double> stream = Stream.generate(() -> Math.random());

        //结束Stream
        //Consumer<T> 的抽象方法  void accept(T t)
        stream.forEach(t-> System.out.println(t));
    }

    @Test
    public void test5(){
        //Stream<T> iterate(final T seed, final UnaryOperator<T> f)
        //seed:种子
        //UnaryOperator<T>: T apply(T t)
//       Stream<Integer> stream =  Stream.iterate(1, t -> t+2);
       Stream<Integer> stream =  Stream.iterate(1, t -> {
           try {
               Thread.sleep(10);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           return t+2;});

        //结束Stream
        //Consumer<T> 的抽象方法  void accept(T t)
        stream.forEach(System.out::println);
    }
}

四、中间操作API

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

序号方 法描 述
1Stream filter(Predicate p)接收 Lambda , 从流中排除某些元素
2Stream distinct()筛选,通过流所生成元素的equals() 去除重复元素
3Stream limit(long maxSize)截断流,使其元素不超过给定数量
4Stream skip(long n)跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
5Stream peek(Consumer action)接收Lambda,对流中的每个数据执行Lambda体操作
6Stream sorted()产生一个新流,其中按自然顺序排序
7Stream sorted(Comparator com)产生一个新流,其中按比较器顺序排序
8Stream map(Function f)接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
9Stream mapToDouble(ToDoubleFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。
10Stream mapToInt(ToIntFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。
11Stream mapToLong(ToLongFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。
12Stream flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
 /*
         需求:给你一组单词,统计里面使用了几个字母,并找出这些字母
         */
  /*
          <R> Stream<R> map(Function<? super T, ? extends R> mapper);
                T类型->R类型对象
         <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
                T类型->Stream<R>流
         */
         
        Set<String> set = Stream.of("hello", "java", "world", "xiaoyu")  //把所有单词的每一个字母取出来
                .flatMap(s -> Arrays.stream(s.split("|")))
                .collect(Collectors.toSet());
        System.out.println("字母有:"+set);
        System.out.println("个数:" + set.size());
        /*
        字母有:[a, d, e, h, i, j, l, o, r, u, v, w, x, y]
        个数:14
         */

案例:

    @Test
    public void test10(){
        //找出最老的3个员工,年龄最大的3个员工
        ArrayList<Employee> list = new ArrayList<>();
        list.add(new Employee(1,"张三",23,15000));
        list.add(new Employee(2,"李四",24,14000));
        list.add(new Employee(3,"王五",25,18000));
        list.add(new Employee(4,"赵六",22,12000));
        list.add(new Employee(5,"陈前",29,12000));
        list.add(new Employee(6,"林上清",27,12000));
        list.add(new Employee(7,"昆昆",27,12000));


        //年龄第3名的员工,年龄值不能重复
        //思路:先找出年龄值是第3的值,然后再找员工
        //Stream 	mapToInt(ToIntFunction f)
        //ToIntFunction<T> int applyAsInt(T value);
        OptionalInt ageOption = list.stream()
                .sorted((t1,t2)->t2.getAge()-t1.getAge())
                .mapToInt(emp -> emp.getAge())
                .distinct()
                .skip(2)
                .findFirst();
        System.out.println("age = " + ageOption);

        list.stream()
                .filter(emp -> emp.getAge() == ageOption.getAsInt())
                .forEach(t-> System.out.println(t));

    }

五、终结操作API

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

序号方法的返回值类型方法描述
1booleanallMatch(Predicate p)检查是否匹配所有元素
2booleananyMatch(Predicate p)检查是否至少匹配一个元素
3booleannoneMatch(Predicate p)检查是否没有匹配所有元素
4OptionalfindFirst()返回第一个元素
5OptionalfindAny()返回当前流中的任意元素
6longcount()返回流中元素总数
7Optionalmax(Comparator c)返回流中最大值
8Optionalmin(Comparator c)返回流中最小值
9voidforEach(Consumer c)迭代
10Treduce(T iden, BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回 T
11Ureduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回 Optional
12Rcollect(Collector c)将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
        Stream<Integer> stream = Stream.of(1, 2, 3, 5, 7, 9);
        
        //判断stream中的所有数据,是否都满足 偶数的要求
        //allMatch(Predicate<? super T> predicate)
        //Predicate<T> boolean test(T t)
        boolean result = stream.allMatch(num -> num % 2 == 0);
        
        //判断stream中的所有数据,是否有数字满足 偶数的要求
        //anyMatch(Predicate<? super T> predicate)
        //Predicate<T> boolean test(T t)
        boolean result = stream.anyMatch(num -> num % 2 == 0);
    }
        
        //判断stream中的所有数据,是否都不满足 偶数的要求
        //noneMatch(Predicate<? super T> predicate)
        //Predicate<T> boolean test(T t)
        boolean result = stream.noneMatch(num -> num % 2 == 0);

        //获取流中第一个元素
        Optional<Integer> first = stream.findFirst();
        
         //加工处理一下,筛选出所有的偶数
        //Stream<T> filter(Predicate<? super T> predicate);
        //Predicate<T> boolean test(T t)
        stream = stream.filter(num -> num%2==0);

        //统计流中的元素个数
        long count = stream.count();
       
        //找出流中的最大值和最小值
        //Comparator<T> int compare(T t1 ,T t2)
        Optional<Integer> max = stream.max((t1, t2) -> t1-t2);
        Optional<Integer> min = stream.min((t1, t2) -> t1 - t2);
        
         //遍历流中的数据
        //  void forEach(Consumer<? super T> action);
        //Consumer<T> 的抽象方法  void accept(T t)
        stream.forEach(t-> System.out.println(t));

        //使用reduce方法找出最大值,不用max方法
        //Optional<T> reduce(BinaryOperator<T> accumulator);
        //BinaryOperator<T,T> T apply(T t1, T t2)
        Optional<Integer> max = stream.reduce((t1, t2) -> t1 > t2 ? t1 : t2);


        //把流中的元素值累加起来
        //Optional<T> reduce(BinaryOperator<T> accumulator);
        //BinaryOperator<T,T> T apply(T t1, T t2)
        final Optional<Integer> sum = stream.reduce((t1, t2) -> t1 + t2);


        //筛选出所有的偶数,放到一个List集合中
        //中间处理
        //Stream<T> filter(Predicate<? super T> predicate);
        //Predicate<T> boolean test(T t)
        stream = stream.filter(t->t%2==0);

        //收集这些元素到List中
        List<Integer> list = stream.collect(Collectors.toList());

        //筛选出所有的偶数,放到一个Set集合中
        //中间处理
        //Stream<T> filter(Predicate<? super T> predicate);
        //Predicate<T> boolean test(T t)
        stream = stream.filter(t->t%2==0);

        Set<Integer> set = stream.collect(Collectors.toSet());

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

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

相关文章

Java面试总结(六)

进程和线程的区别 根本区别&#xff1a; 进程时操作系统资源分配的基本单位&#xff0c;而线程是处理器任务调度和执行的基本单位。 资源开销&#xff1a; 每个进程都有自己独立的代码和数据空间&#xff08;程序上下文&#xff09;&#xff0c;进程之间的切换开销比较大&…

狂扫近300万读者,蟒蛇书升级版即将出版,招募审读人

狂扫全世界近 300 万爱好者成为编程领域的现象级爆品豆瓣累计超过 5000 人评价第2版中文版获得了 9.3 分的好评Amazon 近 10000 人评价第2版原版获得了 4.7 星好评毫不夸张&#xff0c;它是全世界读者心中的 Python 入门圣经因为封面上是一只蠢萌的蟒蛇这本书又被读者亲切地称为…

SQL注入——文件上传

目录 一&#xff0c;mysql文件上传要点 二&#xff0c;文件上传指令 一句话木马 三&#xff0c;实例 1&#xff0c;判断注入方式 2&#xff0c;测试目标网站的闭合方式&#xff1a; 3&#xff0c;写入一句话木马 4&#xff0c;拿到控制权 一&#xff0c;mysql文件上传…

【面试系列】volatile的底层原理

并发编程的三大特性 原子性可见性原子性 JAVA内存模型 Java内存模型&#xff08;Java Memory Model&#xff09;主要分为主内存和线程工作内存。 主内存&#xff1a;方法区和堆空间 线程工作内存&#xff1a;虚拟机栈&#xff0c;本地方法栈&#xff0c;程序计数器。 所有…

centos安装docker详细步骤

目录 一.前言 1.环境要求2.官网中文安装参考手册 二.安装步骤 1.卸载旧版本2.安装需要的软件包3.设置docker镜像源 1.配置docker镜像源 方式1&#xff1a;官网地址(外国)&#xff1a;方式2&#xff1a;阿里云源&#xff1a;2.查看配置是否成功 4.更新yum软件包索引5.可以查看…

C++ | 探究函数重载的原理:函数名修饰【基于Windows + Linux双系统】

文章目录一、前言【中国乒乓和中国男足】【文言文一词多义】二、函数重载概念引入1、参数【类型】不同构成重载2、参数【个数】不同构成重载3、参数【类型顺序】不同构成重载三、函数重载的原理1、回顾程序编译 链接的过程2、Linux下【objdump】查看反汇编3、Windows下反汇编查…

Maven安装与配置,IDEA配置Maven

文章目录1. 安装本地Maven2. 安装3. 配置环境变量4. 配置settings.xml文件5. IDEA配置1. 安装本地Maven 官网下载&#xff1a;https://maven.apache.org/download.cgi 2. 安装 把下载好的maven压缩包解压到一个没有中文&#xff0c;空格或其他特殊字符的文件夹&#xff0c;…

数据结构与算法基础(王卓)(15):KMP算法详解(含速成套路和详细思路剖析)

如果时间不够&#xff0c;急&#xff08;忙&#xff09;着应付考试没心思看&#xff0c;直接参考&#xff08;照抄&#xff09;如下套路&#xff1a; PART 1&#xff1a;关于next [ j ] PPT&#xff1a;P30 根据书上以及视频上给出的思路&#xff08;提醒&#xff09;&#x…

JSONP劫持

注意&#xff1a;仅用于技术讨论&#xff0c;切勿用于其他用途&#xff0c;一切后果与本人无关&#xff01;&#xff01;&#xff01; 个人博客地址&#xff1a;HJW个人博客 扩展&#xff1a; 面试问题&#xff1a;CSRF的两种方法中&#xff0c;CORS和JSONP的区别&#xff1…

dubbo进阶——服务导出

服务导出 在这里记录一下对" Dubbo 导出服务的过程"的研究。 触发时机 public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEv…

代码随想录--数组--螺旋矩阵题型

n等于几&#xff0c;螺旋矩阵最外层行列数就等于几。如n等于3所以最外层一圈的行、列都是3个数字&#xff0c;如左图&#xff0c;n等于4所以最外层的行、列都是4个数字&#xff0c;如右图&#xff1a; 题目要求我们输出(以n3为例)[[123][894][765]]&#xff0c;题目只是给我们一…

MySQL:索引与事物

目录 简单了解索引的底层数据结构 索引的概念&#xff1a; 索引存在的意义&#xff1a; 索引的使用&#xff1a; 索引实现的数据结构 B树 B 树 B 树的特点 B 树的优势 事物 事物的概念 事物的使用 事物的四大特性 并发可能引起的问题 脏读问题 不可重复读 幻读…

未系安全带识别系统 yolo

未系安全带识别系统通过pythonyolo智能视频分析技术&#xff0c;未系安全带识别算法对画面中高空作业人员未系安全带行为进行监测&#xff0c;未系安全带识别算法监测到人员未穿戴安全带时&#xff0c;立即通知后台人员及时处理触发告警。Yolo算法采用一个单独的CNN模型实现end…

算法24:LeetCode_并查集相关算法

目录 题目一&#xff1a;力扣547题&#xff0c;求省份数量 题目二&#xff1a;岛屿数量 题目三&#xff1a;岛屿数量拓展 什么是并查集&#xff0c;举个简单的例子。学生考试通常会以60分为及格分数&#xff0c;我们将60分及以上的人归类为及格学生&#xff0c;而60分以下归…

mysql学习之数据系统概述

☀️马上要成为打工人&#xff0c;这几天把前面的知识都捡了捡&#xff0c;发现自己对关系数据库这块的学习还有所缺失&#xff0c;于是本章开始学习mysql 这里写目录标题1. 数据库系统的发展1.1 人工管理阶段1.2 文件系统阶段1.3 数据库阶段1.4 大数据阶段2 数据库系统的组成2…

扬帆优配|2600亿汽车巨头闪崩近9%,汽车股惊现“冰火两重天”!

今日早盘&#xff0c;A股全体低开震荡调整&#xff0c;首要股指跌逾1%&#xff0c;科创板体现略强&#xff0c;盘中一度直线拉升翻红&#xff0c;两市一度近4200股下跌。 盘面上&#xff0c;轿车服务、信创、半导体等板块相对强势&#xff0c;轿车整车、超导概念、一体压铸、建…

【MySQL】MySQL的索引

目录 介绍 索引的分类 索引的操作-创建索引-单列索引-普通索引 格式 操作 索引的操作-创建索引-单列索引-唯一索引 索引的操作-创建索引-单列索引-主键索引 索引的操作-创建索引-组合索引 索引的操作-全文索引 索引的操作-空间索引 索引的验证 索引的特点 介绍…

Lazada、Allegro、速卖通测评自养号技术(方法解析)

无论是亚马逊、拼多多Temu、shopee、Lazada、wish、速卖通、煤炉、敦煌、雅虎、eBay、TikTok、Newegg、乐天、美客多、阿里国际、沃尔玛、OZON、Joom、Facebook、Coupang、独立站、Cdiscount、Kaufland、DARTY、Allegro、MANO等平台测评自养号对于卖家来说算是一种低成本、高回…

什么?你不知道 ConcurrentHashMap 的 kv 不能为 null?

一、背景 最近设计某个类库时使用了 ConcurrentHashMap 最后遇到了 value 为 null 时报了空指针异常的坑。 本文想探讨下以下几个问题&#xff1a; &#xff08;1&#xff09; Map接口的常见子类的 kv 对 null 的支持情况。 &#xff08;2&#xff09;为什么 ConcurrentHashM…

Ethercat学习-电机调试问题总结

文章目录问题1&#xff1a;初始化不进入OP状态问题2&#xff1a;PDO通讯数据不对主站硬件&#xff1a;STM32F405LAN8720A主站软件&#xff1a;SOEM 问题1&#xff1a;初始化不进入OP状态 现象描述&#xff1a;主站初始化过程中&#xff0c;打印信息显示状态一直在safe-op&…