java8 用流收集数据

正如sql有很多种收集方式一样,用流收集数据也有很多种方式(= = 码字辛苦,点个赞)
1. 把流中的数据收集到一个List中
    * List<Transaction> transactions=
        transactionStream.collect(Collectors.toList());
2.计数(两种方式)
    * long howManyDishes=menu.stream().collect(Collectors.counting());
    * long howManyDishes=menu.stream().count();
3.查找最大值和最小值
    * 使用Collectors.maxBy和Collectors.minBy两个收集器,来计算流中的最大或最小值。
        这两个收集器接收一个Comparator参数来比较流中的元素。
        eg:
        Comparator<Dish> dishCaloriesComParator =
            Comparator.comparingInt(Dish::getCalories);
        Optional<Optional> mostCalorieDish=
            menu.stream()
                .collect(maxBy(dishCaloriesComparator));(Optional是一个容器,可以避免安全性问题,后面会详细介绍)
4.汇总
    * Collectors.summingInt(求和)
        该方法接收一个把对象映射为求和所需int的函数,并返回一个收集器;该收集器在传递给普通的collect方法后即执行我们需要的汇总操作。
        eg:
            int totalCalories=menu.stream().collect(summingInt(Dish::getCalories));
    * Collectors.summingLong和 Collectors.summingDouble
        用法同上
    * Collectors.averagingInt(求平均)
        double avgCalories=
            menu.stream().collect(averagingInt(Dish::getCalories));
    * Collectors.summariZing (同时得到总和、平均值、最大值和最小值)
        IntSummaryStatistics menuStatistics=
            menu.stream().collect(summarizingInt(Dish::getCalories));
5.字符串连接
    * joining
        joining工厂方法返回的收集器会把对流中每一个对象应用toString方法得到的所有字符串连接成一个字符串。
        一种不接受参数,一种接收参数作为分界符
        eg:
            * String shortMenu=menu.stream().map(Dish::getName).collect(joining());
            * String shortMenu=menu.stream().map(Dish::getName).collect(joining(","));
6.广义的规约汇总
    * Collectors.reducing工厂方法
        该方法是所有前面这些特殊情况的一般化。
        * 求和
            * 法1:
                int totalCalories=menu.stream().collect(reducing(0,Dish::getCalories,(i,j)-> i+j));
                注释:0代表起始值,仅仅是为了避免流中没有数据而发生无法预知的错误,Dish::getCalories是选值,最后的是操作.
            * 法2:
                法1,我们说设置0是为了安全性考虑,那么Optional本身提供安全性,我们就可以这么做。
                Optional<Dish> mostCalorieDish=
                    menu.stream().collect(reducing(
                        (d1,d2) ->d1.getCalories()>d2.getCalories() ? d1:d2
                    ));
                    一般来说,mostCalorieDish使用允许提供默认值的方法收集,入orElse或orElseGet来解开Optional中包含的值更安全。
7.分组
    * groupingBy
        给 groupingBy方法传递一个Function,它提取集合中该属性的对象,分组操作的结果是一个Map,把分组函数返回的值作为映射的键,把流中所有具有这个分类值的项目的列表作为对应的映射值。
        eg:
            * 简单分组
                Map<Dish.Type,List<Dish>> dishesByType=
                menu.stream().collect(groupingBy(Dish::getType));
            * 非对象属性分组
                Map<CaloricLevel,List<Dish>> dishesByCaloricLevel=menu.stream().collect(
                    groupingBy(dish ->{
                        if(dish.getCalories()<=400) return CaloricLevel.DIET;
                        else if(dish.getCalories()<=700) return CaloricLevel.NORMAL;
                        else return CaloricLevel.FAT;
                    })
                );
            * 多级分组
                可以这么理解,先按外部分组,然后把外部分组的每一组进行内部分组,在后面可以看到,其实 groupingBy有两个参数,第二个参数就是每组的结果,就是把结果在分组
                eg:
                    Map<Dish.Type,Map<CaloricLevel,List<Dish>>> dishesByCaloricLevel =
                        menu.stream().collect(
                            groupingBy(Dish::getType,
                            groupingBy(dish->{
                                if(dish.getCalories<=400) return CaloricLevel.DIET;
                                else if(dish.getCalories() <=700) return CaloricLevel.NORMAL;
                                else return CaloricLevel.FAT;
                            }))
                        );
    * 按子组收集数据
        * 更换收集结果
            传递给第一个groupingBy的第二个收集器可以是任何类型,而不一定是另一个 groupingBy
            eg:
                Map<Dish.Type,Long> typesCount=menu.stream.collect(groupingBy(Dish::getType,counting()));
                注释:其实groupingBy(f)实际上是groupingBy(f,toList())的简便写法。


                Map<Dish.Type,Optional<Dish>> mostCalorieDish=
                    menu.stream()
                        .collect(groupingBy(Dish::getType,maxBy(comparingInt(Dish::getCalories))));
                    * 把收集器的结果转换为另一种类型
                        诚如这个例子,我们想要的是最小值,但是返回的却是Optional对象,我们需要做一些转换
                        Map<Dish.Type,Dish> mostCalorieDish=
                            menu.stream()
                                .collect(groupingBy(Dish::getType, //分类函数
                                    collectingAndThen(
                                        maxBy(comparingInt(Dish::getCalories)), //包装后的收集器
                                        Optional::get //转换函数
                                    )))
8.分区
    分区是分组的特殊情况:由一个谓词(返回一个布尔值的函数)作为分类函数,它称为分区函数
    eg:
        Map<Boolean,List<Dish>> partitionedMenu=
            menu.stream().collect(partitioningBy(Dish::isVegetarian));
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值