Stream流

体验Stream流【理解】

  • 案例需求

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

    • 创建一个集合,存储多个字符串元素
    • 把集合中所有以"张"开头的元素存储到一个新的集合
    • 把"张"开头的集合中的长度为3的元素存储到一个新的集合
    • 遍历上一步得到的集合
  • 原始方式示例代码

    public class StreamDemo {
    public static void main(String[] args) {
    //创建一个集合,存储多个字符串元素
    ArrayList<String> list = new ArrayList<String>(); list.add("林青霞");
    list.add("张曼玉");
    list.add("王祖贤");
    list.add("柳岩");
    list.add("张敏");
    list.add("张无忌"); //把集合中所有以"张"开头的元素存储到一个新的集合
    ArrayList<String> zhangList = new ArrayList<String>(); for(String s : list) {
    if(s.startsWith("张")) {
    zhangList.add(s);
    }
    } // System.out.println(zhangList); //把"张"开头的集合中的长度为3的元素存储到一个新的集合
    ArrayList<String> threeList = new ArrayList<String>(); for(String s : zhangList) {
    if(s.length() == 3) {
    threeList.add(s);
    }
    } // System.out.println(threeList); //遍历上一步得到的集合
    for(String s : threeList) {
    System.out.println(s);
    }
    System.out.println("--------"); //Stream流来改进
    list.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 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 filter(Predicate predicate) 用于对流中的数据进行过滤
    Stream limit(long maxSize) 返回此流中的元素组成的流,截取前指定参数个数的数据
    Stream skip(long n) 跳过指定参数个数的数据,返回由该流的剩余元素组成的流
    static Stream concat(Stream a, Stream b) 合并a和b两个流为一个流
    Stream distinct() 返回由该流的不同元素(根据Object.equals(Object) )组成的流(自定义数据类型重写equals和hashCode
  • filter原理

          ArrayList list = new ArrayList(List.of(1,2,3,4));
    list.stream().filter(new Predicate() {
    @Override
    public boolean test(Object o) {
    return false;
    }
    });
    //Predicate中有一个抽象方法test可以使用匿名内部类或者lambda表达式
    //filter方法获取流中的每一个数据
    //而test中的s,依次表示流中的每一个数据
    //我们只需要在流中对s进行判断就行了
    //如果判断结果为true,则当前结果留下
    //如果判断结果为false,则当前结果不要
  • filter代码演示

    public class StreamDemo01 {
    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:把list集合中以张开头的元素在控制台输出
    list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
    System.out.println("--------"); //需求2:把list集合中长度为3的元素在控制台输出
    list.stream().filter(s -> s.length() == 3).forEach(System.out::println);
    System.out.println("--------"); //需求3:把list集合中以张开头的,长度为3的元素在控制台输出
    list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
    }
    }
  • 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(System.out::println);
    System.out.println("--------"); //需求2:跳过3个元素,把剩下的元素在控制台输出
    list.stream().skip(3).forEach(System.out::println);
    System.out.println("--------"); //需求3:跳过2个元素,把剩下的元素中前2个在控制台输出
    list.stream().skip(2).limit(2).forEach(System.out::println);
    }
    }
  • 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(System.out::println); //需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复
    Stream.concat(s1,s2).distinct().forEach(System.out::println);
    }
    }

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

  • 概念

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

  • 常见方法

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

    public class StreamDemo {
    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:把集合中的元素在控制台输出
    //list.stream().forEach(System.out::println); //list.stream().forEach(new Consumer() {
    // @Override
    // public void accept(Object o) {
    //
    // }
    // });
    //在forEach方法底层会循环调用流中每一个数据
    //并循环调用accept方法,把每一个数据传递给accept方法
    //s就依次代表流中的每一个数据
    //所以只需要在accept方法中编写相应的业务逻辑即可 //需求2:统计集合中有几个以张开头的元素,并把统计结果在控制台输出
    long count = list.stream().filter(s -> s.startsWith("张")).count();
    System.out.println(count);
    }
    }

Stream流的收集操作【应用】

  • 概念

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

  • 常用方法

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

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

    • 单列集合
    ArrayList<Integer> list = new ArrayList<Integer>(List.of(1, 2, 3, 4,4,4));
    
          //filter负责过滤数据
    //collect负责收集数据
    //获取流中剩余的数据,但是他不负责创建容器,也不负责把数据添加到容器中
    //Collectors.toList()会在底层创建一个List集合,并把所以的数据添加到List集合中。 List<Integer> list1 = list.stream().filter(number -> number % 2 == 0).collect(Collectors.toList());
    System.out.println(list1); Set<Integer> set = list.stream().filter(number -> number % 2 == 0).collect(Collectors.toSet());
    System.out.println(set);
    //[2, 4, 4, 4]
    //[2, 4]
    • 双列集合
    public static void main(String[] args) {
    /**
    * Steam流的收集方法
    *
    * 创建一个ArrayList集合,并添加以下的字符串,字符串中前面是姓名,后面是年龄
    * "zhangsan,23"
    * "lisi,24"
    * "wangwu,25"
    * 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
    */
    ArrayList<String> list = new ArrayList<>(List.of("zhangsan,23","lisi,24","wangwu,25"));
    Map<String,Integer> map = list.stream().filter((String s)->{
    String[] split = s.split(",");
    int i = Integer.parseInt(split[1]);
    return i>=24;
    }).collect(Collectors.toMap(
    (String s)-> {
    return s.split(",")[0];
    },
    (String s)->{
    return Integer.valueOf(s.split(",")[1]);
    }
    ));
    map.forEach((String s,Integer i)->{
    System.out.println(s+"---"+i);
    });
    }

Stream流综合练习【应用】

  • 案例需求

  • 代码实现

    演员类

    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;
    }
    }

    测试类

    package com.cnblogs.gonghr;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.Stream; public class test13 {
    public static void main(String[] args) {
    String actor_man_one = "周润发";
    String actor_man_two = "成龙";
    String actor_man_three = "刘德华";
    String actor_man_four = "吴京";
    String actor_man_five = "周星驰";
    String actor_man_six = "李连杰";
    ArrayList<String> actors_man = new ArrayList<>(List.of(actor_man_one, actor_man_two, actor_man_three, actor_man_four, actor_man_five, actor_man_six));
    String actor_woman_one = "林心如";
    String actor_woman_two = "张曼玉";
    String actor_woman_three = "杨超越";
    String actor_woman_four = "林志玲";
    String actor_woman_five = "周冬雨";
    String actor_woman_six = "杨颖";
    ArrayList<String> actors_woman = new ArrayList<>(List.of(actor_woman_one, actor_woman_two, actor_woman_three, actor_woman_four, actor_woman_five, actor_woman_six));
    Stream<String> actorStream_man= actors_man.stream().filter(actor -> actor.length() == 3).limit(2);
    Stream<String> actorStream_woman = actors_woman.stream().filter(actor -> actor.startsWith("杨")).skip(1);
    Stream.concat(actorStream_man, actorStream_woman).forEach(s->{
    Actor actor = new Actor(s);
    System.out.println(actor);
    });
    }
    }
    //Actor{name='周润发'}
    //Actor{name='刘德华'}
    //Actor{name='杨颖'}

【重学Java】Stream流的更多相关文章

  1. 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...

  2. 重学 Java 设计模式:实战状态模式「模拟系统营销活动,状态流程审核发布上线场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! @ 目录 一.前言 二.开发环境 三.状态模式介绍 四.案例场景模拟 1 ...

  3. 12天,这本《重学Java设计模式》PDF书籍下载量9k,新增粉丝1400人,Github上全球推荐榜!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言

  4. 重学Java(一):与《Java编程思想》的不解之缘

    说起来非常惭愧,我在 2008 年的时候就接触了 Java,但一直到现在(2018 年 10 月 10 日),基础知识依然非常薄弱.用一句话自嘲就是:十年 IT 老兵,Java 菜鸡一枚. 于是,我想 ...

  5. 一文带你入门Java Stream流,太强了

    两个星期以前,就有读者强烈要求我写一篇 Java Stream 流的文章,我说市面上不是已经有很多了吗,结果你猜他怎么说:"就想看你写的啊!"你看你看,多么苍白的喜欢啊.那就&qu ...

  6. 重学 Java 设计模式:实战抽象工厂模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获!

  7. 重学 Java 设计模式:实战单例模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 5个创建型模式的最后一个 在设计模式中按照不同的处理方式共包含三大类:创建型模式.结 ...

  8. 重学 Java 设计模式:实战适配器模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 擦屁屁纸80%的面积都是保护手的! 工作到3年左右很大一部分程序员都想提升自己的技术 ...

  9. 重学 Java 设计模式:实战桥接模式(多支付渠道「微信、支付宝」与多支付模式「刷脸、指纹」场景)

    作者:小傅哥 博客:https://bugstack.cn - 编写系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 为什么你的代码那么多ifelse 同类的业务.同样的功能, ...

  10. 重学 Java 设计模式:实战外观模式「基于SpringBoot开发门面模式中间件,统一控制接口白名单场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你感受到的容易,一定有人为你承担不容易 这句话更像是描述生活的,许许多多的磕磕绊绊总 ...

随机推荐

  1. Pod无法删除 强制删除pod

    多次变更服务后,发现部分pod delete僵死无法删除,一直处于Terminating状态 kubectl delete pod $pod-name一直卡住或不生效 已经删除管理资源的情况下发现仍然 ...

  2. [论文阅读笔记] Community aware random walk for network embedding

    [论文阅读笔记] Community aware random walk for network embedding 本文结构 解决问题 主要贡献 算法原理 参考文献 (1) 解决问题 先前许多算法都 ...

  3. Git 分支基本命令

    1. 查看当前分支 (git branch) 2. 创建分支 (git branch 分支名) 3.切换分支(git checkout 分支名) 4.分支上的常规操作 5.分支的合并 (git che ...

  4. unity editor模式下读取文件夹资源

    string path = EditorUtility.OpenFolderPanel("Load png Textures", "", "" ...

  5. GO语言面向对象06---面向对象练习01

    package main import "fmt" /* 定义动物接口:死.活着 定义动物实现类:鸟.鱼.野兽(跑.捕食) 继承野兽:实现老虎,实现人 业务场景:工作日所有动物都活 ...

  6. Echarts的柱状统计图出现x轴统计时间出现间隔显示的问题

    今天在使用Echarts的柱状统计图出现x轴统计时间出现间隔显示的问题: 数据都拿到了,放到Json数组都是完整的, 展现是时候 如下图:

  7. SpringCloud Alibaba实战(3:存储设计与基础架构设计)

    1.存储设计 在上一章中,我们已经完成了基本业务流程的梳理和服务模块的划分,接下来,开始设计数据存储. 虽然在微服务的理论中,没有对数据库定强制性的规范,但一般,服务拆分之后,数据库也会对应的拆分. ...

  8. 【Azure Developer】使用 Python SDK连接Azure Storage Account, 计算Blob大小代码示例

    问题描述 在微软云环境中,使用python SDK连接存储账号(Storage Account)需要计算Blob大小?虽然Azure提供了一个专用工具Azure Storage Explorer可以统 ...

  9. 前台JS遍历Table的所有单元格数据内容

    在日常开发过程中为了减少与后台服务器的交互次数,大部分的功能都会放到前台使用JS来完成. 例如:一个表中有ID(FOCUS_SEQ)和Name(COLUMNCTRL)两个字段,其中ID是自定义连续增长 ...

  10. SQL进阶总结(二)

    2.第二个特性----以集合为单位进行操作 在我们以往面向过程语言不同,SQL是一门面向集合的一门语言.由于习惯了面向过程的思考方式,导致我们在使用SQL时往往也陷入之前的思维定式. 我们现在分别创建 ...