博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java8 用流收集数据
阅读量:4229 次
发布时间:2019-05-26

本文共 3371 字,大约阅读时间需要 11 分钟。

正如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));

转载地址:http://zmjqi.baihongyu.com/

你可能感兴趣的文章
Administrator's Guide to SQL Server 2005
查看>>
Ajax Design Patterns
查看>>
DNS and BIND (5th Edition)
查看>>
Firewall Fundamentals
查看>>
Learning PHP and MySQL
查看>>
Agile Software Construction
查看>>
Computer Security Basics
查看>>
Sams Teach Yourself MySQL in 10 Minutes
查看>>
Information Systems : The State of the Field
查看>>
IPv6 Essentials
查看>>
Microsoft Visual C++ 2005 Express Edition Programming for the Absolute Beginner
查看>>
Microsoft Visual Basic 2005 Express Edition Programming for the Absolute Beginner
查看>>
Pro .NET 2.0 Windows Forms and Custom Controls in C#
查看>>
Beginning Regular Expressions
查看>>
Beginning Visual Web Developer 2005 Express: From Novice to Professional
查看>>
Beginning Programming
查看>>
Windows .NET Server 2003 Domains & Active Directory
查看>>
Information Systems : Achieving Success by Avoiding Failure
查看>>
Web Systems Design and Online Consumer Behavior
查看>>
VoIP For Dummies
查看>>