• java8-Stream流API


    一回顾与说明

    经过前面发布的三章java8的博客,你就懂得了我们为什么要用Lamda表达式,Lamda表达式的原理与函数式接口的关系,从Lamda表达式到方法引用和构造引用。

    想要学Stream流你必须对前面的知识熟悉并且掌握,今天我们来讲一下Lamda表达式的进阶学习,Stream流API。

    二什么是Stream流

    流想比大家都认识,比如食物的包装过程,先要有个食物员提供食物,食物经过加工处理,添加调料,...,包装,组装。简单的说普通的流就像工厂的流水线一样。

    Stream流是可以能够用声明的方式来操作集合(可以想象sql操作数据库那样),可以将其看作遍历数据集的高级迭代器。在操作流的时候我们就可以将其比喻成工厂中的流水线。

    三 流的优势

    流有什么优势呢?流竟然是一种迭代器,那它与集合的for循环有什么区别,为什么我们要用流来迭代呢?

    • 集合中存放的数据都是计算好的,我们用一次集合遍历,必须有始有终,不能中断。Stream流像视频流一样我们可以先加载一部分,看一部分,中途还能暂停中断离开;相比之集合流更加灵活
    • 流的迭代遍历是一次性的,意味着一个流你只能迭代一次,完成迭代这个流就被消费掉。
    • 流相比于for循环是内部迭代的,我们只要给出具体的函数操作流就ok,而for循环是外部迭代。

    四 Stream流的操作过程

    Stream流跟生产线上的流类式有提供源,操作,终止三个过程
    在这里插入图片描述
    常见的中间操作流:
    在这里插入图片描述
    常见的结束流:​
    在这里插入图片描述

    五常见的StreamAPI

    初始化车辆信息

        public List<Car> InitCar(){
            ArrayList<Car> carList = new ArrayList<>();
            Car car1 = new Car("100", "black", "中国", 20);
            Car car2 = new Car("101", "gray", "中国", 30);
            Car car3 = new Car("102", "yello", "中国", 50);
            Car car4 = new Car("103", "silvery", "英国", 20);
            Car car5 = new Car("104", "red", "英国", 30);
            carList.add(car1);
            carList.add(car2);
            carList.add(car3);
            carList.add(car4);
            carList.add(car5);
            return carList;
        }
    

    1 筛选

    filter函数就是过滤出流中我们需要的元素--中间操作

        @Test
        public void filterTest(){
            // 初始化车辆
            List<Car> cars = carFunFactory.InitCar();
            // 筛选车辆时黑色的车
            List<Car> result = cars.stream()
                    .filter(car -> car.getColor().equals("black"))
                    .collect(Collectors.toList());
            //[Car(code=100, color=black, factory=中国, price=20.0)]
            System.out.println(result);
    
        }
    

    2排序

    sorted函数默认会升序排序元素--中间操纵

       @Test
        public void sortTest(){
            int[] ints = {0, 5, 7, 6, 15, 13, 27};
            Arrays.stream(ints).sorted().forEach(System.out::println);
        }
    

    3 去重

    distinct去掉重复的元素--中间操作

        @Test
        public void distinctTest(){
            int[] ints = {5,6,5,6,27};
            // 5 6 27
            Arrays.stream(ints).distinct().forEach(System.out::println);
        }
    

    4 截断

    limit函数限值流的元素--中间操作

       @Test
        public void limitTest(){
            int[] ints = {5,6,5,6,27};
            // 5 6 
            Arrays.stream(ints).limit(2).forEach(System.out::println);
        }
    

    5跳跃

    skip函数跳过n个元素--中间操作

        @Test
        public void skipTest(){
            int[] ints = {5,6,5,6,27};
            // 27
            Arrays.stream(ints).skip(4).forEach(System.out::println);
        }
    

    6映射

    map是转换函数,接受一个函数为参数,将其映射在每一个元素上,转换成新的元素。--中间操作

        @Test
        public void mapTest(){
            // 初始化车辆
            List<Car> cars = carFunFactory.InitCar();
            // 只获得车的价格
            cars.stream().limit(1)
                    .map(Car::getPrice)
                    .forEach(System.out::println);//20.0
        }
    

    7流的扁平化

    flatMap函数能将中间多个流的内容合并为一个流。--中间操作

        @Test
        public void flatMapTest(){
            String[] array = {"youku1327"};
            // 存放的是一个个数组 [Ljava.lang.String;@61f3fbb8
            Arrays.stream(array).map(s -> s.split(""))
                    .forEach(System.out::print);
            // 将一个个数组流合并为一个流输出:youku1327
            Arrays.stream(array).map(s -> s.split(""))
                    .flatMap(Arrays::stream)
                    .forEach(System.out::print);
        }
    

    8任意匹配

    anyMatch函数任意匹配到流中的一个元素返回真。---终止操作

        @Test
        public void anyMatchTest(){
            // 初始化车辆
            List<Car> cars = carFunFactory.InitCar();
            // 任意匹配黄色的车
            boolean yello = cars.stream()
                    .anyMatch(car -> car.getColor().equals("yello"));
            System.out.println(yello);//true
        }
    
    

    9 完全匹配

    allMatch函数完全匹配流中的元素返回真。--终止操作

       @Test
        public void allMatchTest(){
            // 初始化车辆
            List<Car> cars = carFunFactory.InitCar();
            // 完全匹配黄色的车
            boolean yello = cars.stream()
                    .allMatch(car -> car.getColor().equals("yello"));
            System.out.println(yello);//false
        }
    
    

    10非匹配

    noneMatch函数没有匹配到流中的任意一个元素返回为真。------终止操作

        @Test
        public void noneMatchTest(){
            // 初始化车辆
            List<Car> cars = carFunFactory.InitCar();
            // 不是youku1327这个颜色的车
            boolean yello = cars.stream()
                    .noneMatch(car -> car.getColor().equals("youku1327"));
            System.out.println(yello);//true
        }
    
    

    11任意寻找流中的一个元素

    findAny函数任意查找流中的一个元素返回。---终止操作

        @Test
        public void findAnyTest(){
            // 初始化车辆
            List<Car> cars = carFunFactory.InitCar();
            // 不是youku1327这个颜色的车
            Optional<Car> anyCar = cars.stream().findAny();
            Car car = anyCar.orElse(new Car("141", 50));
            // Car(code=100, color=black, factory=中国, price=20.0)
            System.out.println(car);
        }
    
    

    12 寻找流中的第一个元素

    findFirst函数寻找流中的第一个元素。--------终止操作

        @Test
        public void findFirstTest(){
            // 初始化车辆
            List<Car> cars = carFunFactory.InitCar();
            // 不是youku1327这个颜色的车
            Optional<Car> anyCar = cars.stream().findFirst();
            // Car(code=100, color=black, factory=中国, price=20.0)
            System.out.println(anyCar.get());
        }
    
    

    13 归约

    reduce函数将前一个入参数和后一个入参进行操作后的值做为第下一次操作的前一个入参,以此类推。--终止操作

        @Test
        public void reduceTest(){
            int[] ints = {3,4,5,};
            int reduce = Arrays.stream(ints)
                    .reduce(0, (left, right) -> left + right);
            // 求和 12
            System.out.println(reduce);
            OptionalInt max = Arrays.stream(ints).reduce(Integer::max);
            // 求最大值 5
            System.out.println(max.getAsInt());
            OptionalInt min = Arrays.stream(ints).reduce(Integer::min);
            // 求最小值 3
            System.out.println(min.getAsInt());
        }
    
    

    14数值流

    IntStream 、 DoubleStream 和LongStream ,分别将流中的元素特化为 int 、 long 和 double ,避免自动装箱
    。-----中间操作

        @Test
        public void numTest(){
            int[] ints = {5,6,5,6};
            // int流
            IntStream intStream = Arrays.stream(ints);
            // 6767爱看youku1327
            intStream.mapToObj(value -> value+1).forEach(System.out::print);
            System.out.println("爱看youku1327");
            double[] doubles = {5,6,5,6};
            // double流
            DoubleStream doubleStream = Arrays.stream(doubles);
            //5.06.05.06.0关注youku1327
            doubleStream.forEach(System.out::print);
            System.out.println("关注youku1327");
            // long流
            Long[] longs = {5L,6L,5L,6L};
            Stream<Long> longStream = Arrays.stream(longs);
            long count = longStream.count();
            // 4
            System.out.println(count);
    
        }
    
    

    15 流转换

    boxed函数将数值流转为原始流。-----中间操作

        @Test
        public void streamSwapTest(){
            int[] ints = {5,6,7};
            // 将int流转为原始流
            Optional<Integer> first = Arrays.stream(ints).boxed().findFirst();
            System.out.println(first.get());//5
            // 2.23606797749979  2.449489742783178 2.6457513110645907
            Arrays.stream(ints).boxed()
                    .mapToDouble(s ->Math.sqrt(s))
                    .forEach(System.out::println);
        }
    
    

    六 构建流

    1 数值生成流

        @Test
        public void buildStreamByValue(){
            Stream<String> stream = Stream.of("关", "注", "微", "信", "公", "众", "号", ":", "youku1327", "谢谢");
            //关注微信公众号:youku1327谢谢
            stream.map(StringUtils::join).forEach(System.out::print);
        }
    
    

    2 由数组创建流

     @Test
        public void skipTest(){
            int[] ints = {5,6,5,6,27};
            // 27
            Arrays.stream(ints).skip(4).forEach(System.out::println);
        }
    
    

    3 由文件创建流

        @Test
        public void buildStreamByFile(){
            try {
                Stream<String> lines = Files.lines(Paths.get("C:\mydata\youku1327.txt"), Charset.defaultCharset());
                lines.map(s -> s.split(""))
                        .flatMap(Arrays::stream)
                        .forEach(System.out::print);//youku1327
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    

    4创建无限流

    generate和iterate都是创建无限流,我们要约束一下,以免无线流一直创建元素。

        @Test
        public void buildStreamByIterate(){
            long count = Stream.iterate(1, integer -> integer + 1)
                    .limit(100)
                    .count();
            System.out.println(count);//100
        }
    
    

    七 致谢

    观看完这一篇stream流API操作基本就可以胜任平常工作中的各种场景,后面会继续更新流的高级操作
    最后推一波微信公众号,有兴趣学习的就关注吧。

    在这里插入图片描述

  • 相关阅读:
    Eclipse快捷键 10个最有用的快捷键
    Eclipse--Web项目中 .classpath、mymetadata、project文件的功用
    java.lang.IllegalStateException:Web app root system property already set to different value 错误原因及解决 Log4j
    验证位置时发生错误:“org.tigris.subversion.javahl.ClientException......
    隐藏控制台黑窗口
    APK伪加密
    格蠹汇编-01-blog
    static_cast、dynamic_cast、const_cast和reinterpret_cast总结
    CONTAINING_RECORD宏
    explicit关键字
  • 原文地址:https://www.cnblogs.com/zszxz/p/12066889.html
Copyright © 2020-2023  润新知