Java8笔记第七篇(Stream API 的操作->规约,收集 )

深入 java8 第 07 篇 ( Stream API 的操作->规约,收集 )

一、Stream API 的操作步骤:

  1. 创建 Stream

  2. 中间操作

  3. 终止操作(终端操作 -> 规约,收集)

7.1 规约

reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。 返回 T
reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。 返回 Optional<T>

7.1.1 准备测试数据

    List<Employee> emps = Arrays.asList(
            new Employee(001, "Emma", 41, 20000, Status.FREE),
            new Employee(002, "Mary", 39, 18000, Status.BUSY),
            new Employee(003, "Allen", 33, 15000, Status.BUSY),
            new Employee(004, "Olivia", 52, 32000, Status.FREE),
            new Employee(005, "Natasha", 27, 13000, Status.BUSY),
            new Employee(006, "Kevin", 25, 10000, Status.FREE),
            new Employee(007, "Haivent", 25, 12000, Status.FREE)
    );

    List<Integer> numList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

7.1.2 测试规约

    @Test
    public void test01(){
        // 所有整数累加和
        Integer reduce = numList.stream()
                                .reduce(0, (x,y)->x+y); System.out.println(reduce); // 所有薪资累加和 Optional<Double> reduce2 = emps.stream() .map(Employee::getSalary) .reduce(Double::sum); System.out.println("\n"+reduce2.get()); }

7.1.3 需求:统计所有姓名中 “A” 的出现次数

@Test
    public void test02(){
        Optional<Integer> reduce = emps.stream()
                                    .map(Employee::getName)
                                    .flatMap(StreamAPI03::filterCharacter)
                                    .map((e)->{ if(e.equals('A')){ return 1; }else{ return 0; } }) .reduce(Integer::sum); System.out.println(reduce.get()); } private static Stream<Character> filterCharacter(String str){ List<Character> list = new ArrayList<>(); for (Character ch : str.toCharArray()) { list.add(ch); } return list.stream(); }

7.2 收集

collect(Collector c) 将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法。
Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、 Set、 Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例, 具体方法与实例如下:

方法与实例:

toList 
        List<T> 把流中元素收集到List
toSet 
        Set<T> 把流中元素收集到Set
toCollection 
        Collection<T> 把流中元素收集到创建的集合
counting 
        Long 计算流中元素的个数
summingInt 
        Integer 对流中元素的整数属性求和
averagingInt 
        Double 计算流中元素Integer属性的平均值
summarizingInt 
        IntSummaryStatistics 收集流中Integer属性的统计值。如:平均值
joining 
        String 连接流中每个字符串
maxBy 
        Optional<T> 根据比较器选择最大值
minBy 
        Optional<T> 根据比较器选择最小值
reducing 
        归约产生的类型 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值
collectingAndThen 
        转换函数返回的类型 包裹另一个收集器,对其结果转换函数
groupingBy 
        Map<K, List<T>> 根据某属性值对流分组,属性为K,结果为V
partitioningBy 
        Map<Boolean, List<T>> 根据true或false进行分区

7.2.1 测试收集 收集到集合

    @Test
    public void test03(){
        List<String> collect = emps.stream()
                                .map(Employee::getName)
                                .collect(Collectors.toList());
        collect.forEach(System.out::println);

        System.out.println();
        Set<String> collect2 = emps.stream()
                                    .map(Employee::getName)
                                    .collect(Collectors.toSet());
        collect2.forEach(System.out::println);

        System.out.println();
        ArrayList<String> collect3 = emps.stream()
                                        .map(Employee::getName)
                                        .collect(Collectors.toCollection(ArrayList::new));
        collect3.forEach(System.out::println);

    }

7.2.3 对流中元素进行计算

    @Test
    public void test04(){
        Long collect = emps.stream()
                           .collect(Collectors.counting());
        System.out.println("总员工数:"+collect);

        Double collect2 = emps.stream()
                              .collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println("\n每月应发薪资总额:"+collect2);

        Double collect3 = emps.stream()
                              .collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println("\n员工平均月薪:"+collect3);

        DoubleSummaryStatistics collect4 = emps.stream()
        .collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println("\n员工中最低薪资为:"+collect4.getMin());

        Optional<Double> collect5 = emps.stream()
                                        .map(Employee::getSalary)
                                        .collect(Collectors.maxBy(Double::compare));
        System.out.println("\n员工中薪资最高为:"+collect5.get());

        Optional<Double> collect6 = emps.stream()
                                        .map(Employee::getSalary)
                                        .collect(Collectors.minBy(Double::compare));
        System.out.println("\n员工中薪资最低为:"+collect6.get());

        Optional<Double> collect7 = emps.stream()
                                        .map(Employee::getSalary)
                                        .collect(Collectors.reducing(Double::sum));
        System.out.println("\n员工每月薪资总共为:"+collect7.get());



    }

7.2.4 将多个字符串连接成一个字符串

    @Test
    public void test05(){
        String collect = emps.stream()
                            .map(Employee::getName)
                            .collect(Collectors.joining("-"));
        System.out.println(collect);
    }

7.2.5 对类型转换为集合后,返回集合大小

    @Test
    public void test06(){
        Integer collect = emps.stream()
                              .collect(Collectors.collectingAndThen(Collectors.toList(), List::size));
        System.out.println(collect);
    }

7.2.6 单级分组

    @Test
    public void test07(){
        Map<Status, List<Employee>> collect = emps.stream()
                                                  .collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(collect);
    }

7.2.7 多级分组

    @Test
    public void test08(){
        Map<String, Map<String, List<Employee>>> collect = emps.stream()
                                                            .collect(Collectors.groupingBy((e)->{ if(e.getStatus() == Status.FREE){ return "空闲"; }else{ return "繁忙"; } }, Collectors.groupingBy((e)->{ if(e.getSalary() > 10000){ return "大于 15000"; }else if (e.getSalary() > 20000){ return "大于 20000"; }else{ return "大于25000"; } }))); System.out.println(collect); }

根据员工状态进行分区

    @Test
    public void test09(){
        Map<Boolean, List<Employee>> collect = emps.stream()
                                                .collect(Collectors.partitioningBy((e)->e.getStatus() == Status.FREE)); System.out.println(collect); }

源码下载地址:https://download.csdn.net/download/hello_world_qwp/10401249

    原文作者:csdn-华仔
    原文地址: https://blog.csdn.net/Hello_World_QWP/article/details/80256722
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞