当前位置 博文首页 > 立志欲坚不欲锐,成功在久不在速度:stream流

    立志欲坚不欲锐,成功在久不在速度:stream流

    作者:[db:作者] 时间:2021-07-16 13:17

    ?Stream()的操作:

    package com.example.stream;/*
     * Copyright 2013- Smartdot Technologies Co., Ltd. All rights reserved.
     * SMARTDOT PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
     *
     */
    
    
    import org.apache.ibatis.logging.stdout.StdOutImpl;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import sun.rmi.transport.StreamRemoteCall;
    
    import javax.print.DocFlavor;
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    /**
     * @author
     * @description
     * @since 2021/3/26 11:18
     */
    @SpringBootApplication
    public class main {
    
        public static void main(String[] args) {
            List<String> list=new ArrayList<>();
            for(int i=0;i<10;i++){
                list.add(String.valueOf(i));
            }
            //获取一个顺序流
            Stream<String> stream=list.stream();
            //获取一个并行流
            Stream<String> parallelStream=list.parallelStream();
    
            //使用arrays中的stream()方法,将数据转换成流
            Integer[] nums=new Integer[10];
            Stream<Integer>stream1= Arrays.stream(nums);
    
            /**
             * stream的静态方法: of(),iterate(),generate()
             */
            Stream<Integer> stream2=Stream.of(1,2,3,4);
            //初始值为 0 , 通过迭代函数,生成一个流,迭代次数为3
            Stream<Integer> stream3=Stream.iterate(0,(x) ->x+2).limit(3);
            stream3.forEach(System.out::println);
             //流generate(Supplier s)返回无限顺序无序流,其中每个元素由提供的供应商生成。这适用于生成恒定流,随机元素流等。
            Stream<Double> stream4=Stream.generate(Math::random).limit(3);
            stream4.forEach(System.out::println);
            //等价于:
            Stream<Double> stream5;
            Stream.generate(new Random()::nextDouble).limit(3).forEach(System.out::println);
    
            /**
             * 除了直接创建并行流,还可以通过parallel()把顺序流转换成并行流
             */
            Optional<Integer> findFirst=list.stream().parallel().filter(each->each>4).findFirst();
    
            //无状态操作
            /**
             * filter :筛选,是按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作
             */
            List<Integer> listfilter=Arrays.asList(3,6,7,8);
            Stream<Integer> stream6=listfilter.stream();
            stream6.filter(x->x>5).forEach(System.out::println);
            /**
             * 映射(map,flatMap,peek)
             */
            /**
             * ①map:一个元素类型为 T 的流转换成元素类型为 R 的流,这个方法传入一个Function的函数式接口,
             * 接收一个泛型T,返回泛型R,map函数的定义,返回的流,表示的泛型是R对象;
             *
             *
             * 简言之:将集合中的元素A转换成想要得到的B
             */
    
    
            /**
             * flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
             *
             * 简言之:与Map功能类似,区别在于将结合A的流转换成B流
             *
             */
    
            /**
             * peek: ③peek:peek 操作接收的是一个 Consumer<T> 函数。顾名思义 peek 操作会按照 Consumer<T>
             *     函数提供的逻辑去消费流中的每一个元素,同时有可能改变元素内部的一些属性。
             */
            //你会发现执行之后没有输出任何字符串?
            Stream<String> stream7=Stream.of("hello","felord.cn");
            stream7.peek(System.out::println).collect(Collectors.toList());
            /**
             * 这是因为流的生命周期有三个阶段
             *
             * 起始生成阶段。
             *
             * 中间操作会逐一获取元素并进行处理。可有可无。所有中间操作都是惰性的,因此,流在管道中流动之前,任何操作都不会产生任何影响。
             *
             * 终端操作。通常分为 最终的消费 (foreach 之类的)和 归纳 (collect)两类。还有重要的一点就是终端操作启动了流在管道中的流动。
             *
             */
            //因此我们改为如下即可:
    //        Stream<String> stream7=Stream.of("hello","felord.cn");
    //        stream7.peek(System.out::println).collect(Collectors.toList());
            //有状态 stateful 操作
            // distinct: 返回由该流的不同元素组成的流(去重)  distinct 使用hashCode 和 equals
            Stream<String> stream8=Stream.of("1","3","34","4");
            stream8.distinct().forEach(System.out::println);
            stream8.sorted().distinct().forEach(System.out::println);
    
    //        limit:获取流中n个元素的返回流
             Stream<Integer> stream9=Stream.of(3,20,39,8,9);
             stream.limit(3).forEach(System.out::println);
    
            /**
             * skip :在丢失流的第n个元素之后,返回由该流的其余元素组成的流
             *
             */
            Stream<Integer> stream10=Stream.of(3,40,30,4,3);
            stream10.skip(3).forEach(System.out::println);
    
            /**
             * anyMatch: Steam中只要有一个元素符合传入的值就返回true
             *
             * allMatch: stream中要全部符合传入的值才会返回true
             *
             * noneMatch: stream 中没有一个符合传入的值就会返回true
             */
            Stream<Integer> stream11=Stream.of(3,4,3,4,32,44,3);
            System.out.println("result="+stream11.anyMatch(s->s==3));
            //输入 result=true
    
            /**
             * findFirst 用于返回满足条件的第一个元素
             */
            Stream<Integer> stream12=Stream.of(3,4,30,4,35,43);
            System.out.println(stream12.findFirst().get());
            //输出: 3
            //还可以结合filter进行处理
            System.out.println("result="+stream12.filter(s-> s > 3).findFirst().get());
    
    
            /**
             * forEach 该方法接收一个Lambda表达式,然后在Stream的每一个元素上执行该表达式
             */
            List<String> strList=Arrays.asList("12","3","jark","aray","ark");
            strList.stream().forEach(s->{
                if("jark".equalsIgnoreCase(s)){
                    System.out.println(s);
                }
            });
            //输出结果为 jark
            String aa="jark";
            strList.stream().forEach(s->{
                if(aa.equalsIgnoreCase(s)){
                    System.out.println(s);
                }
            });
    
    
        }
    }
    

    特点:

    使用stream接口从此告别for循环

    流程

    第一步:把集合转换为流stream

    第二步:操作stream流

    第三步:stream流在管道中经过中间操作的处理,最后由最终操作得到前面处理的结束

    操作符:

    两种: 中间操作符,终止操作符

    ?

    map和flatMap的区别:

    map:对流中每一个元素进行处理

    flatMap: 流扁平化,把一个流中的“每个值”都换成另外一个流,然后把所有的流连接起来称为另外一个流

    ?

    看源码应该就能看出来区别了吧

    map函数式接口抽象方法的返回值是R,flatMap函数式接口抽象方法返回值是Stream< R >

    所以flatMap作用就是将返回的Stream< R >拆开,再组合每个值成新的Stream< R >

    @Test
        public void test2() {
            Student[] students = new Student[] { new Student("a.a", 1), new Student("b.b", 2),
                    new Student("c.c", 3), new Student("d.d", 4), new Student("e.e", 5) };
            // Stream流中间操作---映射map
            Arrays.asList(students).stream().map(Student::getName).forEach(System.out::println);
            System.out.println("*********************************");
            // 比较区别,map(s->s.split("\\."))收集之后的结果是Stream<String[]>
            Arrays.asList(students).stream().map(Student::getName).map(s->s.split("\\.")).forEach(arr-> System.out.println(Arrays.toString(arr)));
            System.out.println("*********************************");
            // Stream流中间操作---扁平化映射flatmap,看源码可以发现,Function函数式接口的第二个参数是Stream<? extends R>
            // 也即,lambda表达式的返回值是Stream<? extends R>类型
            // 那作用也就显而易见了,把每个返回值的Stream,再一个个拆开,最后综合所有的变成一个新的Stream
            Arrays.asList(students).stream().map(Student::getName).flatMap(s->Arrays.stream(s.split("\\."))).forEach(System.out::println);
        }

    中间操作:

    /**
         * filter: 过滤不合符条件的
         */
        @Test
        public void filter(){
            List<String> strings= Arrays.asList("a","b","fc");
            //将集合转化为流
            //创建的是串行流 collect(Collectors.toList()) 将流转换成集合
            List<String> filter=strings.stream().filter(str->str.contains("f")).collect(Collectors.toList());
            System.out.println(filter);
            //从这步可以看出中间操作符返回的是流
            Stream<String> d = strings.stream().filter(str -> strings.contains("d"));
            //创建的是并行流
            strings.parallelStream();
        }
    
    
        /**
         * distinct 去重
         */
        @Test
        public void distinct(){
            List<String> strings= Arrays.asList("b","b","c","3");
            Stream<String> distinctd = strings.stream().distinct();
            System.out.println(distinctd);
    
        }
    
        /**
         * 会返回一个不超过给定长度的流
         */
        @Test
        public void limit(){
            List<String> strings= Arrays.asList("b","b","c","3");
            List<String> limited = strings.stream().limit(3).collect(Collectors.toList());
            System.out.println(limited);
        }
    
        /**
         * 获取流中除掉前面的n个元素的其他所有元素
         */
        @Test
        public void skip(){
            List<String> strings= Arrays.asList("b","b","c","3");
            List<String> sout = strings.stream().skip(3).collect(Collectors.toList());
            System.out.println(sout);  //3
        }
        /**
         * 接受一个函数作为参数,这个函数会被应用到每个元素上,并将其映射成一个新的元素
         */
    
        @Test
        public void map(){
            List<String> strings= Arrays.asList("b","b","c","3");
            List<String> collect = strings.stream().map(str ->{
                str.concat("it-heyufu");
                return "a";
                    }
            ).collect(Collectors.toList());
            List<String> collect1 = strings.stream().map(str -> str + "abc").collect(Collectors.toList());
            System.out.println(collect);
            System.out.println(collect1);
            //结果: [bit-heyufu, bit-heyufu, cit-heyufu, 3it-heyufu]
        }
    
        @Test
        public void map2flatmap(){
            List<String> strings= Arrays.asList("bd","bc","cc","3");
            Stream<String> objectStream = strings.stream().flatMap(str -> this.getchar(str));
            List<String> collect = objectStream.collect(Collectors.toList());
            collect.forEach(System.out::println);
            //_____>等价于
            collect.forEach(s-> System.out.println(s));
    
            /**
             * 解析flatmap
             *  扁平化处理
             */
            System.out.println(collect);
            List<String> stringa= Arrays.asList("bd","bc","cc","3");
            Stream<Stream<String>> streamStream = stringa.stream().map(str -> this.getchar(str));
    
        }
    
        /**
         * 功能: 将字符串转换为流
         * @param a
         * @return
         */
        public static Stream<String> getchar(String a){
            List<String> list=Arrays.asList(a);
            Stream<String> stream = list.stream();
            return stream;
        }
    
        @Test
        public void storted(){
            List<String> strings= Arrays.asList("bd","bc","cc","3");
            List<String> collect = strings.stream().sorted().collect(Collectors.toList());
            System.out.println(collect);
        }

    终止操作符

    @Test
        public void collect(){
            List<String> list=Arrays.asList("d","abc","bbb","ddd","bbb","abce");
            //set的形式是有去重的作用
            Set<String> collect = list.stream().collect(Collectors.toSet());
            System.out.println(collect);
    
        }
    
        /**
         *  reduce 可以将流中的元素反复结合起来得到一个结果
         */
        @Test
        public void reduce(){
            List<String> list=Arrays.asList("d","abc","bbb","ddd","bbb","abce");
            Optional<String> reduce = list.stream().reduce((acc, item) -> {
                return acc + item;
            });
            if(reduce.isPresent()) System.out.println(reduce.get());
    
        }
    
        /**
         * 功能描述: 获取集合中元素数量
         */
        @Test
        public void count(){
            List<String> list=Arrays.asList("d","abc","bbb","ddd","bbb","abce");
            long count = list.stream().count();
            System.out.println(count);
        }

    ?

    cs