暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【JavaSE】Java8新特性之Stream API

你的知识书架 2021-08-02
245

Stream是Java8最常用且比较突出的特性,它可以协助你对集合或者数组等“容器”进行非常复杂的查找、过滤和数据映射等操作。


利用Stream完成上述操作需要经历创建流、针对数据流的中间操作和终止操作三个步骤。


下面分别对这三个步骤中涉及的方法进行了总结。


创建Stream流


创建数据流的过程也就是通过数据源(集合、数组)得到流,以备后续操作。


     //创建Stream方式一:通过集合
    @Test
    public void test1() {
    ArrayList<String> arrayList = new ArrayList<>();
    //此种方法得到顺序流
    Stream<String> stream = arrayList.stream();
    //返回一个并行流
    Stream<String> parallelStream = arrayList.parallelStream();
    }


    //创建Stream方式二:通过数组
    @Test
    public void test2() {
    int[] arr = {1, 2, 3, 4};
    IntStream arrStream = Arrays.stream(arr);
    }


    //创建Stream 方式三:通过Stream的of()
    @Test
    public void test3(){
    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);
    }

    上述代码段中提供了三种创建流的方式,而在方式一中stream()方法生成的是顺序流,而parallelStream()生成并行流。


    Stream中间操作


     1-中间操作之过滤与筛选

      @Test
      public void test4(){
      ArrayList<Integer> arrayList = new ArrayList<>();
      for (int i =0; i < 10; i++){
      arrayList.add(i);
      }
      //生成流
      Stream<Integer> stream = arrayList.stream();


      //filter--接受lambda表达式,从流中排除某些元素
      // 过滤出元素大于5的值并打印
      stream.filter(s -> s > 5).forEach(System.out :: println);


      //limit(n) --截断流,使其元素不超过给定数量
      arrayList.stream().limit(6).forEach(System.out::println);


      //skip(n)--跳过元素,n表示跳过元素的数量,若n大于总数,那么返回空流
      arrayList.stream().skip(5).forEach(System.out::println);


      //distinct()--去除流中重复的数据
      arrayList.add(1);
      //可以将重复的1去除
      arrayList.stream().distinct().forEach(System.out::println);
      }

      上述代码片段总结了Stream流中的过滤与筛选操作。


      filter()函数用来过滤不满足要求的元素;limit()表示截断并提取集合中的前n个元素;


      skip()函数表示跳过集合中的前n个元素,返回集合中剩余的元素;distinct()函数表示去除集合中的重复元素。


        2-中间操作之映射

         @Test
        public void test5(){
        ArrayList<Integer> arrayList = new ArrayList<>();
        for (int i =0; i < 10; i++){
        arrayList.add(i);
        }
        //生成流
        Stream<Integer> stream = arrayList.stream();


        //map--接收一个函数,将流中的每个元素经过函数的映射转换为一个新的元素
        // 将集合中的每个元素值都减1
        stream.map(s -> s -1 ).forEach(System.out :: println);

        //flatmap--接收一个函数作为参数,将流中的每个参数都换成另外一个流,然后再把这些流串成一个流返回

        Stream<Integer> stream1 = arrayList.stream().flatMap(StreamAPITest::changeElmToStream);
        stream1.forEach(System.out::println);
        }


        public static Stream<Integer> changeElmToStream(Integer i){
        ArrayList list = new ArrayList();
        list.add(i);
        return list.stream();
        }


        在中间操作之映射操作中,我们介绍了两种方法分别是map()和flatMap(),这两种方法的区别是map()方法只能处理一个集合生成的流,而flatMap()方法可以处理流中包含流的情况。


        上述代码片段中调用StreamAPITest::changeElmToStream方法引用将原集合中的元素都作为一个流返回,这样就形成了一条流中包含了很多流的情况,而flatMap接受这些流之后会有一个类似于合并的操作,也就是将这些流串成一条流并返回。


        3-中间操作之排序

          @Test
          public void test06(){
          //sorted()--自然排序
          List<Integer> integerList = Arrays.asList(12, 98, 20, 63, 78);
          integerList.stream().sorted().forEach(System.out :: println);
          }

          sorted()函数是对集合中的元素进行排序。


          终止操作


          1-终止操作之匹配与查找

             @Test
            public void test07(){
            ArrayList<Integer> arrayList = new ArrayList<>();
            for (int i =0; i < 10; i++){
            arrayList.add(i);
            }
            //生成流
            Stream<Integer> stream = arrayList.stream();


            //allMatch(Predicate p)--检查是否匹配所有元素。
            boolean allMatch = stream.allMatch(e -> e > 0);
            System.out.println(allMatch);//结果返回的是false


            //anyMatch(Predicate p)--检查是否存在某个元素符合条件。
            boolean anyMatch = arrayList.stream().anyMatch(e -> e > 0);
            System.out.println(anyMatch);//返回结果为true


            //noneMatch(Predicate p)--检查是否没有匹配的元素
            boolean noneMatch = arrayList.stream().noneMatch(e -> e < 0);
            System.out.println(noneMatch);//返回结果为true表示集合里没有小于0的元素


            //findFirst()--查找第一个元素
            Optional<Integer> first = arrayList.stream().findFirst();
            System.out.println(first);


            //findAny()--返回集合中的任意一个元素
            Optional<Integer> any = arrayList.stream().findAny();
            System.out.println(any);
            }


            上述代码片段中,allMatch(Predicate p)方法用于检查集合中的每个元素是否都符合p规则,都符合则返回true;


            类似的anyMatch(Predicate p)用于判断是否存在某个元素符合p规则;


            noneMatch(Predicate p)表示是否存在没有符合p规则的元素;findFirst()方法返回集合中第一个元素;


            2-终止操作之返回元素中的个数及最值

              @Test
              public void test08(){
              ArrayList<Integer> arrayList = new ArrayList<>();
              for (int i =0; i < 10; i++){
              arrayList.add(i);
              }
              //生成流
              Stream<Integer> stream = arrayList.stream();
              //count--返回流中的元素个数
              long count = stream.count();
              System.out.println(count);


              //max(Comparator c)--返回集合中的最大值
              Optional<Integer> max = arrayList.stream().max(Integer::compareTo);
              System.out.println(max);


              //min(Comparator c)--返回集合中的最小值
              Optional<Integer> min = arrayList.stream().min(Integer::compareTo);
              System.out.println(min);


              //forEach(Consumer c)--内部迭代
              arrayList.stream().forEach(System.out::println);
              }



              3-终止操作之归约

                 @Test
                public void test09(){
                ArrayList<Integer> arrayList = new ArrayList<>();
                for (int i =0; i < 10; i++){
                arrayList.add(i);
                }
                //生成流
                Stream<Integer> stream = arrayList.stream();
                //reduce(BinaryOperator)
                //可以将流中元素结合起来,得到一个值
                Optional<Integer> reduce = stream.reduce(Integer::sum);
                System.out.println(reduce);
                }


                上述代码段中,reduce()方法中调用求和方法,并将求和的值作为结果返回。


                4-终止操作之收集

                  @Test
                  public void test10(){


                  ArrayList<Integer> arrayList = new ArrayList<>();
                  for (int i =0; i < 10; i++){
                  arrayList.add(i);
                  }
                  //生成流
                  Stream<Integer> stream = arrayList.stream();
                  //collect(Collect c) --将流转换为其他形式。接收一个Collector接口的实现,用于
                  //查找集合中值大于5的数,并将其放在list中返回
                  List<Integer> integerList = stream.filter(e -> e > 5)
                  .collect(Collectors.toList());
                  System.out.println(integerList);
                  }

                  上述代码段中,将集合中元素经过中间操作(filter实现元素过滤),再执行终止操作collect()将过滤剩下的元素转化成list集合返回。这个操作实际上是将流转化为集合的过程。另外Collector还可以调用toMap()方法实现将流转换为Map集合。


                  END

                  文章转载自你的知识书架,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                  评论