java8 用流收集数据

来源:互联网 发布:附近编程培训班 编辑:程序博客网 时间:2024/06/07 22:33
正如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));
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 被甩了很痛苦怎么办 和对象想分手了怎么办 对象想跟你啪啪怎么办 相亲对象好像不太想理我怎么办 想跟对象分手了怎么办 异地恋分手后该怎么办 面膜敷了一晚上怎么办 梦见被刺猬咬了怎么办 梦见死人叫我名字答应怎么办 香瓜苗叶子长斑怎么办 奶油打出来很稀怎么办 寄的水果压坏了怎么办 吃了一个烂水果怎么办 孕期吃了烂水果怎么办 邮快递水果坏了怎么办 快递寄水果坏了怎么办 闲鱼买家拒收水果怎么办 洗澡桶里有很多老鼠屎怎么办? 塑料和金属断了怎么办 孕妇吃了沙拉酱怎么办 孕妇淀粉吃多了怎么办 怀孕初期吃了杏怎么办 如果睡觉吃梨了怎么办 怀孕6个月有点贫血怎么办 怀孕八个多月有点贫血怎么办 生完小孩身体虚怎么办 孩子咳嗽厉害怎么办吃什么药 新生儿三天不拉大便怎么办 胃吃的变大了怎么办 小孩长高长的慢怎么办 小孩长高长得慢怎么办 小孩吃东西不吸收营养怎么办 婴儿长得太快怎么办 2个月婴儿长太快怎么办 孩子脚长得太快怎么办 4个月宝宝缺钙怎么办 2个月宝宝不长肉怎么办 小孩子长得不高怎么办 宝宝误吃蜂蜜了怎么办 有人拿着吃完的东西退货怎么办 婴儿个子长的慢怎么办