• Stream 流


    Stream API

    1 创建

    什么是 Stream?

    在这里插入图片描述
    Stream的操作步骤:

    在这里插入图片描述

    创建流:(的几种方法如下)

    /**
    * 创建流
    */
    @Test
    public void test01(){
        /**
        * 集合流
        *  - Collection.stream() 穿行流
        *  - Collection.parallelStream() 并行流
        */
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();
    
        //数组流
        //Arrays.stream(array)
        String[] strings = new String[10];
        Stream<String> stream2 = Arrays.stream(strings);
    
        //Stream 静态方法
        //Stream.of(...)
        Stream<Integer> stream3 = Stream.of(1, 2, 3);
    
        //无限流
        //迭代
        Stream<Integer> stream4 = Stream.iterate(0, (i) -> ++i+i++);
        stream4.forEach(System.out::println);
    
        //生成
        Stream.generate(() -> Math.random())
            .limit(5)
            .forEach(System.out::println);
    }
    

    2 筛选 / 切片

    中间操作:

    • filter:接收 Lambda ,从流中排除某些元素
    • limit:截断流,使其元素不超过给定数量
    • skip(n):跳过元素,返回一个舍弃了前n个元素的流;若流中元素不足n个,则返回一个空流;与 limit(n) 互补
    • distinct:筛选,通过流所生成的 hashCode() 与 equals() 取除重复元素
    List<Employee> emps = Arrays.asList(
        new Employee(101, "Z3", 19, 9999.99),
        new Employee(102, "L4", 20, 7777.77),
        new Employee(103, "W5", 35, 6666.66),
        new Employee(104, "Tom", 44, 1111.11),
        new Employee(105, "Jerry", 60, 4444.44)
    );
    
    @Test
    public void test01(){
        emps.stream()
            .filter((x) -> x.getAge() > 35)
            .limit(3) //短路?达到满足不再内部迭代
            .distinct()
            .skip(1)
            .forEach(System.out::println);
    
    }
    

    Stream的中间操作:
    在这里插入图片描述

    • 内部迭代:迭代操作由 Stream API 完成
    • 外部迭代:我们通过迭代器完成

    3 映射

    • map:接收 Lambda ,将元素转换为其他形式或提取信息;接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
    • flatMap:接收一个函数作为参数,将流中每一个值都换成另一个流,然后把所有流重新连接成一个流

    map:

    @Test
    public void test02(){
        List<String> list = Arrays.asList("a", "b", "c");
        list.stream()
            .map((str) -> str.toUpperCase())
            .forEach(System.out::println);
    }
    

    flatMap:

    public Stream<Character> filterCharacter(String str){
        List<Character> list = new ArrayList<>();
        for (char c : str.toCharArray()) {
            list.add(c);
        }
    
        return list.stream();
    }
    
    @Test
    public void test03(){
        List<String> list = Arrays.asList("a", "b", "c");
        Test02 test02 = new Test02();
        list.stream()
            .flatMap(test02::filterCharacter)
            .forEach(System.out::println);
    }
    

    4 排序

    • sorted():自然排序
    • sorted(Comparator c):定制排序

    Comparable:自然排序

    @Test
    public void test04(){
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        list.stream()
            .sorted() //comparaTo()
            .forEach(System.out::println);
    }
    

    Comparator:定制排序

    @Test
    public void test05(){
        emps.stream()
            .sorted((e1, e2) -> { //compara()
                if (e1.getAge().equals(e2.getAge())){
                    return e1.getName().compareTo(e2.getName());
                } else {
                    return e1.getAge().compareTo(e2.getAge());
                }
            })
            .forEach(System.out::println);
    }
    

    5 查找 / 匹配

    终止操作:

    • allMatch:检查是否匹配所有元素
    • anyMatch:检查是否至少匹配一个元素
    • noneMatch:检查是否没有匹配所有元素
    • findFirst:返回第一个元素
    • findAny:返回当前流中的任意元素
    • count:返回流中元素的总个数
    • max:返回流中最大值
    • min:返回流中最小值
    public enum Status {
        FREE, BUSY, VOCATION;
    }
    
    @Test
    public void test01(){
        List<Status> list = Arrays.asList(Status.FREE, Status.BUSY, Status.VOCATION);
    
        boolean flag1 = list.stream()
            .allMatch((s) -> s.equals(Status.BUSY));
        System.out.println(flag1);
    
        boolean flag2 = list.stream()
            .anyMatch((s) -> s.equals(Status.BUSY));
        System.out.println(flag2);
    
        boolean flag3 = list.stream()
            .noneMatch((s) -> s.equals(Status.BUSY));
        System.out.println(flag3);
    
        // 避免空指针异常
        Optional<Status> op1 = list.stream()
            .findFirst();
        // 如果Optional为空 找一个替代的对象
        Status s1 = op1.orElse(Status.BUSY);
        System.out.println(s1);
    
        Optional<Status> op2 = list.stream()
            .findAny();
        System.out.println(op2);
    
        long count = list.stream()
            .count();
        System.out.println(count);
    }
    

    6 归约 / 收集

    • 归约:reduce(T identity, BinaryOperator) / reduce(BinaryOperator) 可以将流中的数据反复结合起来,得到一个值
    • 收集:collect 将流转换成其他形式;接收一个 Collector 接口的实现,用于给流中元素做汇总的方法

    reduce:

    /**
    * Java:
    *  - reduce:需提供默认值(初始值)
    * Kotlin:
    *  - fold:不需要默认值(初始值)
    *  - reduce:需提供默认值(初始值)
    */
    @Test
    public void test01(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Integer integer = list.stream()
            .reduce(0, (x, y) -> x + y);
        System.out.println(integer);
    }
    

    collect:

    在这里插入图片描述

    List<Employee> emps = Arrays.asList(
        new Employee(101, "Z3", 19, 9999.99),
        new Employee(102, "L4", 20, 7777.77),
        new Employee(103, "W5", 35, 6666.66),
        new Employee(104, "Tom", 44, 1111.11),
        new Employee(105, "Jerry", 60, 4444.44)
    );
    
    @Test
    public void test02(){
        //放入List
        List<String> list = emps.stream()
            .map(Employee::getName)
            .collect(Collectors.toList()); 
        list.forEach(System.out::println);
        
    	//放入Set
        Set<String> set = emps.stream()
            .map(Employee::getName)
            .collect(Collectors.toSet());
        set.forEach(System.out::println);
    
        //放入LinkedHashSet
        LinkedHashSet<String> linkedHashSet = emps.stream()
            .map(Employee::getName)
            .collect(Collectors.toCollection(LinkedHashSet::new));
        linkedHashSet.forEach(System.out::println);
    }
    
    @Test
    public void test03(){
        //总数
        Long count = emps.stream()
            .collect(Collectors.counting());
        System.out.println(count);
    
        //平均值
        Double avg = emps.stream()
            .collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println(avg);
    
        //总和
        Double sum = emps.stream()
            .collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println(sum);
    
        //最大值
        Optional<Employee> max = emps.stream()
            .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println(max.get());
    
        //最小值
        Optional<Double> min = emps.stream()
            .map(Employee::getSalary)
            .collect(Collectors.minBy(Double::compare));
        System.out.println(min.get());
    }
    
    @Test
    public void test04(){
        //分组
        Map<Integer, List<Employee>> map = emps.stream()
            .collect(Collectors.groupingBy(Employee::getId));
        System.out.println(map);
    
        //多级分组
        Map<Integer, Map<String, List<Employee>>> mapMap = emps.stream()
            .collect(Collectors.groupingBy(Employee::getId, Collectors.groupingBy((e) -> {
                if (e.getAge() > 35) {
                    return "开除";
                } else {
                    return "继续加班";
                }
            })));
        System.out.println(mapMap);
        
        //分区
        Map<Boolean, List<Employee>> listMap = emps.stream()
            .collect(Collectors.partitioningBy((e) -> e.getSalary() > 4321));
        System.out.println(listMap);
    }
    
    @Test
    public void test05(){
        //总结
        DoubleSummaryStatistics dss = emps.stream()
            .collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(dss.getMax());
        System.out.println(dss.getMin());
        System.out.println(dss.getSum());
        System.out.println(dss.getCount());
        System.out.println(dss.getAverage());
        
        //连接
        String str = emps.stream()
            .map(Employee::getName)
            .collect(Collectors.joining("-")); //可传入分隔符
        System.out.println(str);
    }
    
  • 相关阅读:
    设置导航条上的主题一颜色
    luogu_2158【题解】欧拉函数
    luogu_1313【题解】二项式定理
    【数论学习笔记】高斯消元
    luogu_2524【题解】康托展开
    luogu_1495【题解】中国剩余定理
    【数论学习笔记】 约数
    luogu_4430 luogu_4981【题解】 Cayley定理
    【数论学习笔记】质数
    【数论学习笔记】同余
  • 原文地址:https://www.cnblogs.com/yangzhixue/p/14300678.html
Copyright © 2020-2023  润新知