Java学习笔记 --- Stream流

news2024/11/24 16:20:57

一、体验Stream流【理解】

  • 案例需求

    按照下面的要求完成集合的创建和遍历

    • 创建一个集合,存储多个字符串元素

    • 把集合中所有以"张"开头的元素存储到一个新的集合

    • 把"张"开头的集合中的长度为3的元素存储到一个新的集合

    • 遍历上一步得到的集合

  • 原始方式示例代码

public class MyStream1 {
    public static void main(String[] args) {
        //集合的批量添加
        ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));
        //list.add()

        //遍历list1把以张开头的元素添加到list2中。
        ArrayList<String> list2 = new ArrayList<>();
        for (String s : list1) {
            if(s.startsWith("张")){
                list2.add(s);
            }
        }
        //遍历list2集合,把其中长度为3的元素,再添加到list3中。
        ArrayList<String> list3 = new ArrayList<>();
        for (String s : list2) {
            if(s.length() == 3){
                list3.add(s);
            }
        }
        for (String s : list3) {
            System.out.println(s);
        }      
    }
}
  • 使用Stream流示例代码
public class StreamDemo {
    public static void main(String[] args) {
        //集合的批量添加
        ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));

        //Stream流
        list1.stream().filter(s->s.startsWith("张"))
                .filter(s->s.length() == 3)
                .forEach(s-> System.out.println(s));
    }
}
  • Stream流的好处

    • 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印

    • Stream流把真正的函数式编程风格引入到Java中

    • 代码简洁

 

 

二、Stream流的常见生成方式【应用】

  • Stream流的思想

  • Stream流的三类方法

    • 获取Stream流

      • 创建一条流水线,并把数据放到流水线上准备进行操作

    • 中间方法

      • 流水线上的操作

      • 一次操作完毕之后,还可以继续进行其他操作

    • 终结方法

      • 一个Stream流只能有一个终结方法

      • 是流水线上的最后一个操作

  • 生成Stream流的方式

    • Collection体系集合

      使用默认方法stream()生成流, default Stream<E> stream()

    • Map体系集合

      把Map转成Set集合,间接的生成流

    • 数组

      通过Arrays中的静态方法stream生成流

    • 同种数据类型的多个数据

      通过Stream接口的静态方法of(T... values)生成流

  • 代码演示

public class StreamDemo {
    public static void main(String[] args) {
        //Collection体系的集合可以使用默认方法stream()生成流
        List<String> list = new ArrayList<String>();
        Stream<String> listStream = list.stream();

        Set<String> set = new HashSet<String>();
        Stream<String> setStream = set.stream();

        //Map体系的集合间接的生成流
        Map<String,Integer> map = new HashMap<String, Integer>();
        Stream<String> keyStream = map.keySet().stream();
        Stream<Integer> valueStream = map.values().stream();
        Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();

        //数组可以通过Arrays中的静态方法stream生成流
        String[] strArray = {"hello","world","java"};
        Stream<String> strArrayStream = Arrays.stream(strArray);
      
      	//同种数据类型的多个数据可以通过Stream接口的静态方法of(T... values)生成流
        Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
        Stream<Integer> intStream = Stream.of(10, 20, 30);
    }
}

  

 

三、Stream流中间操作方法【应用】

  • 概念

    中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作

  • 常见方法

    方法名说明
    Stream<T> filter(Predicate predicate)用于对流中的数据进行过滤
    Stream<T> limit(long maxSize)返回此流中的元素组成的流,截取前指定参数个数的数据
    Stream<T> skip(long n)跳过指定参数个数的数据,返回由该流的剩余元素组成的流
    static <T> Stream<T> concat(Stream a, Stream b)合并a和b两个流为一个流
    Stream<T> distinct()返回由该流的不同元素(根据Object.equals(Object) )组成的流

filter代码演示

public class MyStream3 {
    public static void main(String[] args) {
//        Stream<T> filter(Predicate predicate):过滤
//        Predicate接口中的方法	boolean test(T t):对给定的参数进行判断,返回一个布尔值

        ArrayList<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张无忌");
        list.add("张翠山");
        list.add("王二麻子");
        list.add("张良");
        list.add("谢广坤");

        //filter方法获取流中的 每一个数据.
        //而test方法中的s,就依次表示流中的每一个数据.
        //我们只要在test方法中对s进行判断就可以了.
        //如果判断的结果为true,则当前的数据留下
        //如果判断的结果为false,则当前数据就不要.
//        list.stream().filter(
//                new Predicate<String>() {
//                    @Override
//                    public boolean test(String s) {
//                        boolean result = s.startsWith("张");
//                        return result;
//                    }
//                }
//        ).forEach(s-> System.out.println(s));

        //因为Predicate接口中只有一个抽象方法test
        //所以我们可以使用lambda表达式来简化
//        list.stream().filter(
//                (String s)->{
//                    boolean result = s.startsWith("张");
//                        return result;
//                }
//        ).forEach(s-> System.out.println(s));

        list.stream().filter(s ->s.startsWith("张")).forEach(s-> System.out.println(s));

    }
}

limit&skip代码演示

public class StreamDemo02 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:取前3个数据在控制台输出
        list.stream().limit(3).forEach(s-> System.out.println(s));
        System.out.println("--------");

        //需求2:跳过3个元素,把剩下的元素在控制台输出
        list.stream().skip(3).forEach(s-> System.out.println(s));
        System.out.println("--------");

        //需求3:跳过2个元素,把剩下的元素中前2个在控制台输出
        list.stream().skip(2).limit(2).forEach(s-> System.out.println(s));
    }
}

concat&distinct代码演示

public class StreamDemo03 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:取前4个数据组成一个流
        Stream<String> s1 = list.stream().limit(4);

        //需求2:跳过2个数据组成一个流
        Stream<String> s2 = list.stream().skip(2);

        //需求3:合并需求1和需求2得到的流,并把结果在控制台输出
//        Stream.concat(s1,s2).forEach(s-> System.out.println(s));

        //需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复
        Stream.concat(s1,s2).distinct().forEach(s-> System.out.println(s));
    }
}

 

 

四、Stream流终结操作方法【应用】

  • 概念

    终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作

  • 常见方法

    方法名说明
    void forEach(Consumer action)对此流的每个元素执行操作
    long count()返回此流中的元素数
  • 代码演示

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

        //method1(list);
        
//        long count():返回此流中的元素数
        long count = list.stream().count();
        System.out.println(count);
    }

    private static void method1(ArrayList<String> list) {
        //  void forEach(Consumer action):对此流的每个元素执行操作
        //  Consumer接口中的方法void accept(T t):对给定的参数执行此操作
        //在forEach方法的底层,会循环获取到流中的每一个数据.
        //并循环调用accept方法,并把每一个数据传递给accept方法
        //s就依次表示了流中的每一个数据.
        //所以,我们只要在accept方法中,写上处理的业务逻辑就可以了.
        list.stream().forEach(
                new Consumer<String>() {
                    @Override
                    public void accept(String s) {
                        System.out.println(s);
                    }
                }
        );
      
        System.out.println("====================");
        //lambda表达式的简化格式
        //是因为Consumer接口中,只有一个accept方法
        list.stream().forEach(
                (String s)->{
                    System.out.println(s);
                }
        );
        System.out.println("====================");
        //lambda表达式还是可以进一步简化的.
        list.stream().forEach(s->System.out.println(s));
    }
}

 

 

五、Stream流的收集操作【应用】

  • 概念

    对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中

  • 常用方法

    方法名说明
    R collect(Collector collector)把结果收集到集合中
  • 工具类Collectors提供了具体的收集方式

    方法名说明
    public static <T> Collector toList()把元素收集到List集合中
    public static <T> Collector toSet()把元素收集到Set集合中
    public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中
  • 代码演示

// toList和toSet方法演示 
public class MyStream7 {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            list1.add(i);
        }

        list1.add(10);
        list1.add(10);
        list1.add(10);
        list1.add(10);
        list1.add(10);

        //filter负责过滤数据的.
        //collect负责收集数据.
                //获取流中剩余的数据,但是他不负责创建容器,也不负责把数据添加到容器中.
        //Collectors.toList() : 在底层会创建一个List集合.并把所有的数据添加到List集合中.
        List<Integer> list = list1.stream().filter(number -> number % 2 == 0)
                .collect(Collectors.toList());

        System.out.println(list);

    Set<Integer> set = list1.stream().filter(number -> number % 2 == 0)
            .collect(Collectors.toSet());
    System.out.println(set);
}
}
/**
Stream流的收集方法 toMap方法演示
创建一个ArrayList集合,并添加以下字符串。字符串中前面是姓名,后面是年龄
"zhangsan,23"
"lisi,24"
"wangwu,25"
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
*/
public class MyStream8 {
	public static void main(String[] args) {
      	ArrayList<String> list = new ArrayList<>();
        list.add("zhangsan,23");
        list.add("lisi,24");
        list.add("wangwu,25");

        Map<String, Integer> map = list.stream().filter(
                s -> {
                    String[] split = s.split(",");
                    int age = Integer.parseInt(split[1]);
                    return age >= 24;
                }

         //   collect方法只能获取到流中剩余的每一个数据.
         //在底层不能创建容器,也不能把数据添加到容器当中

         //Collectors.toMap 创建一个map集合并将数据添加到集合当中

          // s 依次表示流中的每一个数据

          //第一个lambda表达式就是如何获取到Map中的键
          //第二个lambda表达式就是如何获取Map中的值
        ).collect(Collectors.toMap(
                s -> s.split(",")[0],
                s -> Integer.parseInt(s.split(",")[1]) ));

        System.out.println(map);
	}
}

 

 

六、Stream流综合练习【应用】

  • 案例需求

    现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作

    • 男演员只要名字为3个字的前三人

    • 女演员只要姓林的,并且不要第一个

    • 把过滤后的男演员姓名和女演员姓名合并到一起

    • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据

    演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法

  • 代码实现

    演员类

public class Actor {
    private String name;

    public Actor(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

测试类

public class StreamTest {
    public static void main(String[] args) {
        //创建集合
        ArrayList<String> manList = new ArrayList<String>();
        manList.add("周润发");
        manList.add("成龙");
        manList.add("刘德华");
        manList.add("吴京");
        manList.add("周星驰");
        manList.add("李连杰");
  
        ArrayList<String> womanList = new ArrayList<String>();
        womanList.add("林心如");
        womanList.add("张曼玉");
        womanList.add("林青霞");
        womanList.add("柳岩");
        womanList.add("林志玲");
        womanList.add("王祖贤");
  
        //男演员只要名字为3个字的前三人
        Stream<String> manStream = manList.stream().filter(s -> s.length() == 3).limit(3);
  
        //女演员只要姓林的,并且不要第一个
        Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);
  
        //把过滤后的男演员姓名和女演员姓名合并到一起
        Stream<String> stream = Stream.concat(manStream, womanStream);
  
      	// 将流中的数据封装成Actor对象之后打印
      	stream.forEach(name -> {
            Actor actor = new Actor(name);
            System.out.println(actor);
        }); 
    }
}

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

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

相关文章

使用群晖NAS Mail Server搭建个性化邮件系统

准备工作 一个顶级域名可以获取公网IP的宽带路由使用DDNS功能&#xff0c;或使用群晖自带DDNS&#xff0c;解析顶级域名可以做“端口映射”的路由器 搭建开始 step1&#xff1a;安装套件 登录群晖NAS&#xff0c;打开[套件中心]&#xff0c;搜索“mail”&#xff0c;安装如…

idea-easyYapi的使用

链接: EasyYapi官方文档. 网上搜到的easyYapi基本上都是千篇一律&#xff0c;比较浅&#xff0c;稍微有点定制的东西都搜不到&#xff0c;帮此把自己的一些心得写出来&#xff0c;后续有新发现也会继续更新 第一步&#xff1a;安装插件 第二步&#xff1a;配置数据 yapi的t…

运营商大数据助力贷款行业快速精准获取意向客户

流量&#xff0c;是企业发展的一大痛点。随着市场格局不断变化&#xff0c;获取流量越来越成为企业摆脱发展困局的一种重要途径&#xff0c;如何在庞大的市场竞争中&#xff0c;实现自身的流量突破&#xff0c;也成为企业所要解决的首要问题。 贷款行业的竞争也很强烈&#xf…

一文总结MySQL面试知识点

文章目录 知识点1 定位慢查询2 存储引擎3 索引4 SQL优化5 事务6 主从同步7 分库分表 问答题1 如何定位慢查询2 那这个SQL语句执行很慢, 如何分析呢&#xff1f;3 MYSQL支持的存储引擎有哪些, 有什么区别 ?4 了解过索引吗&#xff1f;&#xff08;什么是索引&#xff09;5 索引…

录取分数爆降102分,只招一个人也敢报考的狠人!

本期为大家整理热门院校-“华南理工大学”的择校分析&#xff0c;这个择校分析专题会为大家结合&#xff1a;初试复试占比、复试录取规则&#xff08;是否公平&#xff09;、往年录取录取名单、招生人数、分数线、专业课难度等进行分析。希望能够帮到大家! –所有数据来源于研…

排班工具小程序开源版开发

排班工具小程序开源版开发 以下是排班工具小程序可能包含的功能列表&#xff1a; 用户注册和登录功能&#xff0c;支持微信登录和手机号登录。排班管理功能&#xff0c;包括创建、编辑、删除和查询排班表。排班表展示功能&#xff0c;支持按天、周、月等不同时间维度展示排班…

Apache DolphinScheduler 开源之夏学生项目申请开启,6 大课题等你来拿万元奖金!

开源之夏 2023 学生报名已经正式开启&#xff01;Apache DolphinScheduler 今年继续参与开源之夏的活动&#xff0c;2023 年 4 月 29 日-6 月 3 日 15:00 UTC8&#xff0c;同学们可以在开源之夏官网 https://summer-ospp.ac.cn/ 找到 Apache DolphinScheduler 下的项目&#xf…

i春秋 Misc Web 爆破-2

审计一下代码&#xff0c;和爆破-1的区别是&#xff0c;没有了正则匹配&#xff0c;且可变变量$$a变成了普通变量$a&#xff1b; 尝试像爆破-1那样传入超全局变量$GLOBALS 根据回显&#xff0c;我们发现flag不在变量中&#xff08;它还嘲笑我们“too young too simple”太年轻…

后端注册表单验证器实现

视图函数在去注册用户之前需要进行验证&#xff0c;表单验证需要先下载 flask-wtf 在终端执行&#xff1a; pip install flask-wtf新建forms.py import wtforms from wtforms.validators import Email,Length,EqualTo from models import UserModel,EmailCaptchaModel# Form…

详细的步骤在VirtualBox 上安装 CentOS 7

下面是详细的步骤来安装 CentOS 7 在 VirtualBox 上&#xff1a; 下载 CentOS 7 ISO 镜像文件&#xff1a; 前往 CentOS 官方网站的镜像下载页面&#xff1a;Download在页面上找到适合你系统架构的 CentOS 7 ISO 镜像文件&#xff0c;并下载到本地。 安装 VirtualBox&#x…

为什么大部分企业都选择加密软件来防止数据泄露?

加密软件是使用加密算法对数据或信息进行编码转换的软件&#xff0c;目的是防止未授权访问与保护敏感内容。它是实现加密技术的重要手段&#xff0c;为用户提供了简单易用的加解密功能&#xff0c;无需深入了解复杂的数学原理。 加密软件使用的加密算法通常采用对称与非对称算法…

16 KVM虚拟机配置-其他常见配置项

文章目录 16 KVM虚拟机配置-其他常见配置项16.1 概述16.2 元素介绍16.3 配置示例 16 KVM虚拟机配置-其他常见配置项 16.1 概述 除系统资源和虚拟设备外&#xff0c;XML配置文件还需要配置一些其他元素&#xff0c;本节介绍这些元素的配置方法。 16.2 元素介绍 iothreads&…

干货丨手把手教会群晖Mailplus设置及邮件免拒收(SPF、DMARC、DKIM)

开篇之前&#xff0c;我想说通过群晖 Mailplus Server 自建一个邮件服务器绝对是一个非常有成就感的事情&#xff0c;搭建 过程中我们可以学习到邮件服务使用的协议&#xff0c;端口号&#xff0c;MX解析等很多知识。如果你已经准备好&#xff0c;那就让 我们开始吧。 前期准备…

前端013_标签模块_新增功能

标签模块_新增功能 1、需求分析2、新增窗口实现3、列表引用新增组件4、关闭弹出窗口5、校验表单数据6、提交表单数据6.1 EasyMock 添加新增模拟接口6.2、Api 调用接口1、需求分析 点击 新增 按钮后,对话框形式弹出新增窗口输入类别信息后,点击 确定 提交表单数据; 2、新增窗…

DARWIN Survival of the Fittest Fuzzing Mutators读论文笔记

DARWIN: Survival of the Fittest Fuzzing Mutators 作者背景 达姆施塔特工业大学&#xff1a;成立于1877年&#xff0c;是德国著名理工科大学 ‡萨格勒布大学: 是克罗地亚最大的大学&#xff0c;也是该地区历史最悠久的大学 拉德堡德大学:位于荷兰奈梅亨市&#xff0c;又称奈梅…

Redis与SpringBoot的集成:自定义RedisTemplate类,创建一个工具类:可以帮助我们更好的使用redis中的API

这里使用的环境是在windows环境下&#xff0c;也可以放在服务器中&#xff0c;只要知道端口号和ip即可&#xff0c;如果有不知道怎么部署环境的可以看这篇文章去在Windows环境下去部署redis环境redis之jedis&#xff1a;通过redis的API与Java的集成_不想睡醒的梦的博客-CSDN博客…

css的clip-path学习

文章目录 clip-path的几个值polygon多边形circle圆形ellipse椭圆形inset 矩形round后面是四个角的度数 一个简单的应用&#xff0c;比如画一段曲线 参考博文 clip-path的几个值 自己学习后&#xff0c;先把clip-path理解为在原图上绘制轮廓&#xff0c;显示的内容是轮廓内的内…

2023苹果商务管理模式分发app完全指南

随着苹果对企业级开发证书的管控越来越严格&#xff0c;越来越多的企业级证书到期后&#xff0c;苹果不再予以续约&#xff0c;但是很多app都有企业内部分发需求&#xff0c;不希望自己的应用被公开上架。这时候&#xff0c;我们可以参考苹果官方的建议&#xff0c;使用商务管理…

繁华三千如梦散,红尘俗世要释怀

岁月的折痕在眼角盛开&#xff0c;一深&#xff0c;一浅&#xff0c;交错着旧时光的梦。 梦里是累积的回忆&#xff0c;厚厚的凌乱一地。 那些&#xff0c;都是悄悄溜走的充满烟火气的日子。 生活像是流水账一般&#xff0c;就这样过了&#xff0c;一天又一天&#xff0c;一年…

ConcurrentHashMap进阶面试题

ConcurrentHashMap 1.8的优化 存储的时候的优化写数据的时候加锁的优化扩容时的优化&#xff0c;有一个协助扩容的概念计数器的优化&#xff0c;在记录元素个数时&#xff0c;使用的类似与longAdder的形式&#xff0c;不会过度消耗CPU资源 为什么多线程情况下longAdder会比ato…