(详细+示例)JDK8新特性三:Stream流+常见方法演示

目录

第一篇:JDK8新特性一:引入介绍
第二篇:JDK8新特性二:Lambda表达式引入介绍
第三篇:JDK8新特性二:Lambda表达式规范和语法
第四篇:JDK8新特性二:方法引入详述
第五篇:JDK8新特性二:foreach、排序、线程调用简单示例
第六篇:JDK8新特性三:Stream流+常见方法演示
第七篇:JDK8新特性四:Optional类的学习

Stream流

1 什么是Stream流

  • java.util.stream.Stream
  • Stream是JDK1.8中处理集合的关键抽象概念,Lambda和Stream是JDK1.8新增的函数式编程最有亮点的特性,它可以指定我们需要对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用StreamAPI对集合数据进行操作,类似于使用SQL执行数据库查询。Stream使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的抽象。Stream API可以极大提高Java编程的生产力,让程序员写出高效率、干净、简洁的代码。
  • 这种风格将要处理的元素集合看做一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选、排序、聚合等。
  • 元素流在管道中经过中间操作的处理,最后由最终操作得到前面处理之后的结果。
  • 示例图
    • img
  • Stream操作的步骤
    • 创建Stream:一个数据源(如集合、数组),获取一个流
    • 中间操作:一个操作链,对数据源的数据进行处理
    • 终止操作:一个终止操作,执行中间操作链并产生结果

2 Stream创建方式

  • 两种Stream流创建方式

    • stream:是串行流,采用单线程执行
    • parallelStream:是并行流,采用多线程执行
  • 获取流的方式

    • 根据Collection获取流

      • 从Collection接口源码中可以看到,其中添加了default方法stream用来获取流对象,因此该接口的所有实现类都可以通过这种方式获取流
      • image-20210804143054083
      // 1. Collection获取流
      List<String> list = new ArrayList<>();
      Stream<String> stream1 = list.stream();
      
      Set<String> set = new HashSet<>();
      Stream<String> stream2 = set.stream();
      
      Vector<String> vector = new Vector<>();
      Stream<String> stream3 = vector.stream();
      
    • 根据Map获取流

      • Map接口并不是Collection接口的子接口,因此没法直接通过stream()方式获取流,此外因为Map是K-V形式的结构数据,不符合流元素的单一特征,因此还要划分Key、Value、entry等方面
      // 2. 根据Map获取流
      Map<String, String> map = new HashMap<>();
      Stream<String> keyStream = map.keySet().stream();
      Stream<String> valueStream = map.values().stream();
      Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
      
    • 根据数组获取流

      • 数组对象不存在默认方法,在Stream接口中的静态方法of可以用来操作数据获取流
      // 3. 通过数组获取流
      String[] strArr = {
             
             "111","222","333"};
      Stream<String> strStream = Stream.of(strArr);
      
      • image-20210804152904083
      • Stream.of的形参是可变参数,可以接收数组为参数,也可以给定一个元素序列,返回一个流对象
      • 对于数组的操作,还可以使用Arrays.stream(T arr)来操作
  • 流的常见方法,后面案例会用一部分来演示

    • 分类

      • 延迟方法:返回值仍然是Stream接口自身类型的方法,因此支持链式调用。(除了终结方法之外的方法都是延迟方法)
      • 终结方法:返回值类型不再是Stream接口自身类型的方法,因此不再支持类似StringBuilder那样的链式调用。终结方法包括count和forEach等方法。
    • 举例

      forEach:遍历处理
      filter:过滤
      map:处理映射
      reduce:元素反复结合,生成一个值
      count:统计个数
      limit:截取前几个
      skip:忽略前几个
      concat:流合并为一个流
      sorted:排序
      allMatch:检查是否匹配所有元素
      anyMatch:检查是否至少匹配一个元素
      noneMatch:检查是否一个都没有匹配
      findFirst:返回第一个元素
      findAny:返回任意一个元素
      max:返回最大值
      min:返回最小值
      collect:将流转换其他形式
      

3 Stream将List转换为Set

  • 使用到的方法

    • stream.collect(Collectors.toSet())
  • 测试实体类

    @Data
    @AllArgsConstructor
    public class TestEntity {
         
         
        private String name;
        private Integer age;
    }
    
  • 测试

    List<TestEntity> list = new ArrayList<>();
    TestEntity tom2 = new TestEntity("Tom2", 2);
    list.add(new TestEntity("Tom1",1));
    list.add(tom2);
    list.add(new TestEntity("Tom3",3));
    list.add(tom2);
    list.add(new TestEntity("Tom5",5));
    // 创建Stream流
    Stream<TestEntity> stream = list.stream();
    // 1. 将List集合转换为Set,乱序|不允许重复|返回Set为HashSet
    Set<TestEntity> set = stream.collect(Collectors.toSet());
    System.out.println(set);
    
  • 说明

    • 集合中的泛型实体类必须要重写hashCode方法,因为stream.collect(Collectors.toSet())方法返回的Set是HashSet类型,它对速度进行了优化,存入HashSet的元素必须定义hashCode()方法。同时在良好编程风格来看,同样需要重写equals方法
    • 测试代码中,添加的两个tom2指向同一个对象,因此转换为Set对象之后,只会保留一个
    • 可以进入toSet()方法源码,这里指明了方法返回值是什么具体的Set类型
      • image-20210729153310329
      • image-20210729153326896

4 Stream将List转换为Map

  • 测试实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class TestEntity {
         
         
        private String name;
        private Integer age;
    }
    
  • 测试代码

    List<TestEntity> list = new ArrayList<>();
    list.add(new TestEntity("Tom1",1));
    list.add(new TestEntity("Tom2",2));
    list.add(new TestEntity("Tom3",3));
    list.add(new TestEntity("Tom4",4));
    list.add(new TestEntity("Tom5",5));
    // 创建Stream流
    Stream<TestEntity> stream = list.stream();
    // 将List集合转换为Map
    //        Map<String, TestEntity> collect = stream.collect(Collectors.toMap(new Function<TestEntity, String>() {
         
         
    //            @Override
    //            public String apply(TestEntity testEntity) {
         
         
    //                return testEntity.getName();
    //            }
    //        }, new Function<TestEntity, TestEntity>() {
         
         
    //            @Override
    //            public TestEntity apply(TestEntity testEntity) {
         
         
    //                return testEntity;
    //            }
    //        }));
    // Lambda优化
    Map<String, TestEntity> collect = stream.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值