【JAVA入门】Day34 - Stream流

news2024/12/25 23:36:17

【JAVA入门】Day34 - Stream流


文章目录

  • 【JAVA入门】Day34 - Stream流
    • 一、Stream 流的作用和使用步骤
    • 1.Stream流的创建,数据的添加
    • 2. Stream流的中间方法
    • 3. Stream流的终结方法


        Stream 流有什么作用?我们看一个例子:

【练习】需求:按照下面的要求完成集合的创建和遍历。
①把所有以“张”开头的元素存储到新集合中。
②把“张”开头的,长度为3的元素再存储到新集合中。
③遍历打印最终结果。
        以往我们是这样写的。

package Stream;

import java.util.ArrayList;

public class StreamDemo {
    public static void main(String[] args) {
        /*①把所有以“张”开头的元素存储到新集合中。
②把“张”开头的,长度为3的元素再存储到新集合中。
③遍历打印最终结果。*/
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张无忌");
        list1.add("周芷若");
        list1.add("赵敏");
        list1.add("张强");
        list1.add("张三丰");

        //①把所有以“张”开头的元素存储到新集合中。
        ArrayList<String> list2 = new ArrayList<>();
        for (String name : list1) {
            if(name.startsWith("张")){
                list2.add(name);
            }
        }

        System.out.println(list2);

        //②把“张”开头的,长度为3的元素再存储到新集合中。
        ArrayList<String> list3 = new ArrayList<>();
        for (String name : list2) {
            if(name.length() == 3){
                list3.add(name);
            }
        }

        System.out.println(list3);

        //③遍历打印最终结果。
        for (String s : list3) {
            System.out.println(s);
        }
    }
}

        使用 Stream 流我们可以这样写。

package Stream;

import java.util.ArrayList;

public class StreamDemo1 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张无忌");
        list1.add("周芷若");
        list1.add("赵敏");
        list1.add("张强");
        list1.add("张三丰");

        list1.stream().filter(name->name.startsWith("张")).filter(name -> name.length() == 3).forEach(name -> System.out.println(name));
    }
}

        一行代码就完成了所有任务。可以说是大大简化了代码。

一、Stream 流的作用和使用步骤

        Stream 本身是结合了 Lambda 表达式,简化了集合、数组的各种操作。
        Stream的使用理论步骤是:
①先得到一条 Stream 流(流水线),并把数据放上去。
②利用 Stream 流中的 API 进行各种操作,包括:过滤、转换、统计、打印等等。
        Stream 流中的方法分为两种:中间方法(过滤、转换)、终结方法(统计、打印)。中间方法就是调用完毕之后还可以调用其他方法;终结方法就是流的最后一步,调用完毕之后,不能再调用其他方法。
        下面我们根据步骤分别介绍相关方法。
在这里插入图片描述

1.Stream流的创建,数据的添加

1.单列集合创建流水线:

package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class StreamDemo2 {
    public static void main(String[] args) {
        //1.单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"a","b","c","d","e");

        /*//获取一条流水线,把集合中的数据放到流水线上
        Stream<String> stream1 = list.stream();
        //使用终结方法打印流水线上所有数据
        stream1.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

        //利用Lambda表达式简化
        list.stream().forEach(s -> System.out.println(s));
    }
}

2.双列集合间接使用流水线:

package Stream;

import java.util.HashMap;

public class StreamDemo3 {
    public static void main(String[] args) {
        //1.创建一个双列集合
        HashMap<String,Integer> hm = new HashMap<>();

        //2.添加数据
        hm.put("aaa",111);
        hm.put("bbb",222);
        hm.put("ccc",333);
        hm.put("ddd",444);

        //3.获取stream流,放入键
        hm.keySet().stream().forEach(s -> System.out.println(s));

        //4.第二种获取stream流的办法,放入键值对
        hm.entrySet().stream().forEach(s -> System.out.println(s));
    }
}

3.数组使用流水线:

package Stream;

import java.util.Arrays;

public class StreamDemo4 {
    public static void main(String[] args) {
        //1.创建数组
        int[] arr = {1,2,3,4,5,6,7,8,9,10};
        String[] arr2 = {"a","b","c","d","e"};
        //2.创建stream流
        Arrays.stream(arr).forEach(s -> System.out.println(s));
        Arrays.stream(arr2).forEach(s -> System.out.println(s));
    }
}

4.大量零散数据使用流水线:

package Stream;

import java.util.stream.Stream;

public class StreamDemo5 {
    public static void main(String[] args) {
        //public static<T> Stream<T> of(T...values)     Stream接口中的静态方法
        Stream.of(1,2,3,4,5).forEach(s -> System.out.println(s));

        Stream.of("a","b","c","d","e").forEach(s -> System.out.println(s));
    }
}

要注意:

//数组可以作为Stream.of()的参数,但必须是引用类型的,如果传递基本数据类型的数组,会把整个数组当成一个元素放入Stream
Stream.of(arr2).forEach(s -> System.out.println(s));

2. Stream流的中间方法

        Stream 流的中间方法如下。
在这里插入图片描述
        其中要注意 distinct() 方法去重,依赖于那两个常用方法,如果要去重的是自定义数据类型,务必重写这两个方法。
        还要注意:中间方法会返回新的 Stream 流,而原来的 Stream 流只能用一次(调一次方法就关闭了),所以建议使用链式编程节省代码量。
        还要注意:修改 Stream 流中的数据是不会影响原来集合或者数组中的数据的。
        部分方法使用例代码如下。

package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Predicate;

public class StreamDemo6 {
    public static void main(String[] args) {
        /*
            filter  过滤
            limit   获取前几个元素
            skip    跳过前几个元素
         */

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张三丰","张翠山","张良","王二麻子","谢广坤");

        //filter 过滤 把“张”开头的留下,其他不要
        /*list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                //如果返回值为true,表示当前数据留下
                //如果返回值为false,表示当前数据舍弃不要
                return s.startsWith("张");
            }
        }).forEach(s -> System.out.println(s));*/

        list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));
        //原集合没有发生变化
        System.out.println(list);   //[张无忌, 周芷若, 赵敏, 张三丰, 张翠山, 张良, 王二麻子, 谢广坤]
		
    }
}
package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Stream;

public class StreamDemo7 {
    public static void main(String[] args) {
        /*
            distinct 元素去重,依赖hashCode和equals方法
            concat   合并a和b两个流为一个流
         */

        ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1, "张无忌","张无忌","张无忌","张强","张三丰","张翠山","张良","王二麻子","谢广坤");

        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list2,"周芷若","赵敏");

        //元素去重
        list1.stream().distinct().forEach(s -> System.out.println(s));

        //流的合并
        Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.println(s));
    }
}
package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;

public class StreamDemo8 {
    public static void main(String[] args) {
        /*
            map     转换流中的数据类型
         */

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌-15","周芷若-14","赵敏-13","张强-20","张三丰-100","张翠山-40","张良-35","王二麻子-37","谢广坤-41");

        //获取里面的年龄并进行打印
        //第一个类型:表示流中原本的数据类型
        //第二个类型:表示要转换之后的数据类型
        //apply的形参s:表示流里面的每一个数据
        //返回值:表示转换之后的数据类型
        list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                String[] arr = s.split("-");
                String ageString = arr[1];                  //arr[0]是名字,arr[1]是年龄
                int age = Integer.parseInt(ageString);
                return age;
            }
        }).forEach(s -> System.out.println(s));

        //简写为Lambda表达式
        list.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s -> System.out.println(s));
    }
}

3. Stream流的终结方法

        Stream 的终结方法使用完毕后,Stream 流就关闭了,所以要写在最后。
在这里插入图片描述
        以下演示了如何遍历、统计一个流中的数据,并将流中的数据收集到一个数组当中,使用的方法是 toArray(),其中的代码都可以用 Lambda 表达式来改写。

package Stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.IntFunction;

public class StreamDemo9 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌","张无忌","张无忌","张强","张三丰","张翠山","张良","王二麻子","谢广坤");

        //void forEach(Consumer action) 遍历
        //重写的方法体是对每一个数据的操作
/*
        list.stream().forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
*/

        list.stream().forEach(s -> System.out.println(s));

        //long count() 统计
        System.out.println(list.stream().count());

        //toArray() 收集流中数据,放入数组中
        Object[] arr1 = list.stream().toArray();                //空参是转化为Object类型,放入Object数组中
        System.out.println(Arrays.toString(arr1));              //调用Arrays.toString方法转化为字符串打印

        //IntFunction的泛型是:具体类型的数组 <? extends Object[]>
        //apply方法的形参:流中数据的个数,要和数组长度保持一致
        //apply的返回值:返回具体的类型的数组
        //apply的方法体:创建数组,流中有多少数据,数组长度就填多少
        //toArray方法整体这个实现类参数的作用是:创建一个指定类型的数组
        //toArray方法的底层会依次得到流中每一个数据,并把数据放入数组中
        //toArray方法的返回值是一个装着流里所有数据的数组
/*        String[] arr = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
*/

        String[] arr2 = list.stream().toArray(value -> new String[value]);
        System.out.println(Arrays.toString(arr2));
    }
}

        以下的代码将演示如何使用 collect() 方法将流中的数据收集到各种集合(List、Set、Map)当中。

package Stream;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class StreamDemo10 {
    public static void main(String[] args) {
        /*
                collect(Collector collector)        收集流中数据,放入集合中(List Set Map)
         */

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌-男-15","周芷若-女-14","赵敏-女-13","张强-男-20","张三丰-男-100","张翠山-女-40","张良-男-35","王二麻子-男-37","谢广坤-男-41");

        //1.收集到List集合中
        //需求:收集所有男性

        List<String> newList = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());
        System.out.println(newList);

        //2.收集到Set集合中
        //需求:收集所有男性
        //收集到Set中时,数据会自动去重,且无序
        Set<String> newSet = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toSet());
        System.out.println(newSet);

        //3.收集到Map集合中
        //需求:收集所有男性,键:姓名,值:年龄
        //toMap:参数一:生成键的规则,参数二:生成值的规则,两个参数都是new Function实现类
        //第一个new Function<流里面每一个数据的类型,键里面数据的类型>
        //第二个new Function<流里面每一个数据的类型,值里面数据的类型>
        //apply方法形参:依次表示流中每一个数据,方法体:生成键/值,返回值:生成的键/值
        /*
          注意点:如果要把数据收集到Map当中,那么键是不能有重复的,否则代码会报错
         */
        /*Map<String, Integer> newMap = list.stream()
        	.filter(s -> "男".equals(s.split("-")[1]))
        	.collect(Collectors.toMap(new Function<String, String>() {
            @Override
            public String apply(String s) {
                //张无忌-男-15
                //键是名字,对应0索引
                return s.split("-")[0];
            }
        }, new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                //张无忌-男-15
                //值是年龄,对应2索引
                return Integer.parseInt(s.split("-")[2]);
            }
        }));*/

        //改写为Lambda表达式
        Map<String, Integer> newMap = list.stream()
        	.filter(s -> "男".equals(s.split("-")[1])).collect(Collectors
        	.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[2])));

        System.out.println(newMap);

    }
}

【练习1】定义一个集合,并添加一些整数1, 2, 3, 4, 5, 6, 7, 8, 9, 10。
要求过滤奇数,只留下偶数,并保存结果。

package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class StreamDemo11 {
    public static void main(String[] args) {
        /*
        定义一个集合,并添加一些整数1, 2, 3, 4, 5, 6, 7, 8, 9, 10。
            要求过滤奇数,只留下偶数,并保存结果。
         */
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        //过滤奇数,只留下偶数
        List<Integer> newList = list.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
        System.out.println(newList);
    }
}

【练习2】创建一个 ArrayList 集合,并添加以下字符串,字符串前面是姓名,后面是年龄:
“zhangsan,23” “lisi,24” “wangwu,25”,保留年龄大于等于24岁的人,并把结果放入 Map 中,姓名为键,年龄为值。

package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;

public class StreamDemo12 {
    public static void main(String[] args) {
        /*
    创建一个 ArrayList 集合,并添加以下字符串,字符串前面是姓名,后面是年龄:
    "zhangsan,23" "lisi,24" "wangwu,25",保留年龄大于等于24岁的人,并把结果放入 Map 中,姓名为键,年龄为值。
     */

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"zhangsan,23" ,"lisi,24" ,"wangwu,25");

        //1.建立流过滤器
        Map<String, Integer> map = list.stream()
                .filter(s -> Integer.parseInt(s.split(",")[1]) >= 24)
                .collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));

        //2.打印
        System.out.println(map);
    }

}

【练习3】如下。
在这里插入图片描述

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

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

相关文章

SQL的高级查询练习知识点下(day26)

1 学习目标 重点掌握分组查询的语法 重点掌握分页查询的语法 2 分页查询 2.1 语法 SELECT 字段|表达式,... FROM 表 [WHERE 条件] [GROUP BY 分组字段] [HAVING 条件] [ORDER BY 排序的字段] LIMIT [起始的条目索引,]条目数; 2.2 特点 起始条目索引从0开始 limit子句放在…

ARM32开发——GD32F4 DMA功能查询

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 DMA0DMA1 DMA0 DMA1

蔬菜识别数据集 蔬菜数据集 用于训练,有十种蔬菜,如图已经标注好的版本

数据集概述 该数据集包含十种常见的蔬菜&#xff1a;胡萝卜、包菜、水果辣椒、青瓜、南瓜、土豆、花菜和西红柿。数据集已经进行了精细的标注&#xff0c;适用于深度学习模型的训练&#xff0c;尤其是用于物体检测和分类任务。 数据集特点 种类多样&#xff1a;涵盖了八种蔬菜…

Github 2024-09-07Rust开源项目日报Top10

根据Github Trendings的统计,今日(2024-09-07统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10CUE项目1Python项目1Go项目1Polars: Rust中的DataFrame接口和OLAP查询引擎 创建周期:1354 天开发语言:Rust, Python协议类型:MIT …

Vue-Pinia状态管理案列Demo

上一篇文章已经介绍了pinia的基本使用&#xff0c;现在做一个小的案列来巩固。 数据绑定修改pinia中的状态。 在页面刷新的时候会显示pinia中的数据 import { createApp } from vue // import ./style.css import App from ./App.vueimport { createPinia } from pinia cons…

心觉:接纳父母,就是接纳自己---创富第一步

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松搞定人生挑战&#xff0c;实现心中梦想&#xff01; 挑战日更写作162/1000(完整记录在下面) 公门洞开纳百川 众心逐梦越千山 号召引领潜力绽 心觉潜意识无间 很多人抱怨父母&…

Linux是如何收发网络包的

Linux网 络协议栈 从上述⽹络协议栈&#xff0c;可以看出&#xff1a; 收发流程 ⽹卡是计算机⾥的⼀个硬件&#xff0c;专⻔负责接收和发送⽹络包&#xff0c;当⽹卡接收到⼀个⽹络包后&#xff0c;会通过 DMA 技术&#xff0c;将⽹络包放⼊到 Ring Buffer &#xff0c;这个是…

解决 Tomcat 启动时 JAR 包 `Invalid byte tag in constant pool` 异常问题

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

未来出行:高效智能的汽车充电桩

解析高效智能的汽车充电桩的结构设计技术要求 充电桩按照充电方式分为交流充电桩与直流充电桩、交直流一体充电桩三种。直流充电桩一般安装在高速公路&#xff0c;充电站等地&#xff1b;交流充电桩一般安装在小区、停车场、道路停车位、高速公路服务区等位置。根据国网Q/GDW4…

[3.4]【机器人运动学MATLAB实战分析】PUMA560机器人正运动学MATLAB计算

PUMA560是六自由度关节型机器人,其6个关节都是转动副,属于6R型操作臂。各连杆坐标系如图1,连杆参数如表1所示。 图1 PUMA560机器人的各连杆坐标系 表1 PUMA560机器人的连杆参数 按D-H方法建立操作臂运动学方程。建立PUMA560机器人运动学方程的步骤如下࿱

【网络安全】Jenkins任意文件读取漏洞及检测工具(CVE-2024-23897)

原创文章,不得转载。 文章目录 漏洞成因影响范围检测工具更多细节漏洞成因 Jenkins CLI 接口存在任意文件读取漏洞(CVE-2024-23897)。该问题源于 args4j 库在解析文件名参数时,会将@符号后的字符串视为文件名并尝试读取文件,而且该功能默认处于启用状态。 影响范围 Jen…

部署Apache网站

简易部署自己的apache网站 写在前面&#xff1a;先安装好mysql&#xff0c;再来搭建站点 1.安装php [rootlocalhost ~]# yum install php -y ##安装了php&#xff0c;默认会和apache结合工作2.创建文件编写php网页代码 [rootlocalhost ~]# vim /var/www/html/index.php ##创…

1-6 图像覆盖掩膜 opencv树莓派4B 入门系列笔记

目录 一、提前准备 二、代码详解 hsv cv2.cvtColor(img, cv2.COLOR_BGR2HSV) lower_range np.array([101, 100, 100], dtypenp.uint8) upper_range np.array([121, 255, 255], dtypenp.uint8) mask cv2.inRange(hsv, lower_range, upper_range) mask2 cv2.inRange(…

【Python】数据可视化之分类图

目录 条形图 箱形图 散点图 分簇散点图 小提琴 分簇小提琴 条形图 条形图是一种直观的图表形式&#xff0c;它通过不同长度的矩形条&#xff08;即“条形”&#xff09;来展示数值变量的中心趋势估计值&#xff0c;其中每个矩形的高度直接对应于该组数据的某个中心量度&…

urdf ( xacro ) 的 collision碰撞参数设置

目录 写在前面的话整体流程1 URDF 文件结构2 查看原始碰撞形状描述3 加入简单碰撞形状描述方法一 Meshlab 自动测量方法二 人为测量 4 加入XACRO函数简化描述 最终结果展示侧视图正视图碰撞几何体中心点设置不对出现的结果 写在前面的话 本文使用的 URDF 文件是由 solidworks …

百度飞浆OCR半自动标注软件OCRLabel配置【详细

今天帮标注人员写了一份完整的百度飞浆OCR标注软件的安装配置说明书、以供标注人员使用 包括各种环境安装包一起分享出来【conda\python\label项目包、清华源配置文件、pycharm社区版安装包】 提取码&#xff1a;umys 1、解压并安装tools文件下的miniconda,建议安装在D盘下的…

【docker】基于docker-compose 安装elasticsearch + kibana + ik分词器(8.10.4版本)

记录下&#xff0c;使用 docker-compose 安装 Elasticsearch 和 Kibana&#xff0c;并配置 IK 分词器&#xff0c;你可以按照以下步骤进行。此过程适用于 Elasticsearch 和 Kibana 8.10.4 版本。 安装 首先&#xff0c;在你的工作目录下创建一个 docker-compose.yml 文件&…

Java基础-IO相关

文章目录 类层次结构1. java.io 包整体示意图核心类字节流&#xff08;Byte Stream&#xff09;字符流&#xff08;Character Stream&#xff09;其他辅助类 2. java.nio 包示意图核心类文件操作 总结 字符流读写1. 字符流的核心类1.1 Reader 和 Writer 2. 常用的字符流类2.1 字…

vue3写一个无限树形菜单,递归组件

原本使用element plus的el-tree&#xff0c;可是他的UI不匹配&#xff0c;狠难改成自己想要的&#xff0c;所以只能自己去写一个&#xff0c;做法&#xff1a;使用递归组件 效果 组件代码itemDir.vue // itemDir.vue<template><div><ul v-for"node in li…

Java+Swing+sqlserver学生成绩管理系统

JavaSwingsqlserver学生成绩管理系统 一、系统介绍二、系统展示1.登陆2.课程分配3.选课管理4.学生打分--教师4.查询个人成绩--学生 三、其他1.其它系统 一、系统介绍 管理员:登陆页面、课程管理、选课管理 老师&#xff1a;给学生打分 学生&#xff1a;查询个人成绩 二、系…