JDK8 Collectors 使用篇(四)

news/2024/7/23 9:43:58

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

#Collectors 使用 在之前篇章中,我们探讨了Lambdas、函数式接口编程、Stream的使用。现在拿collectors 耍耍.

Collectors是一个reduce操作,通过collectors 可以把一个结合转换成另外一个集合collection,Map, 或者一个值。

来看看collectors能干什么:

##1.分组 groupby


public class Jdk8_collector_groupby_test {

    private static class User {
        private String name;
        private String password;

       //省略getter setter
    }

    public static void main(String[] args) {
        List<User> userList = constructUserList();

        //使用JDK8 按照名字分组
        Map<String, List<User>> userMaps = userList.stream().collect(Collectors.groupingBy(u -> u.getName()));
        //按照密码分组
        Map<String, List<User>> userPasswordMaps = userList.stream().collect(Collectors.groupingBy(u -> u.getPassword()));

        userMaps.forEach((key, groupUser) -> {
            System.out.println("---------------- group by user name = " + key + "----------");
            groupUser.forEach(u -> System.out.println(u.getPassword()));
        });
        userPasswordMaps.forEach((key, groupUser) -> {
            System.out.println("----------------  group by user password = " + key + "----------");
            groupUser.forEach(u -> System.out.println(u.getName()));
        });

        //上面的例子想想用JKD7写,表示博主很懒
        Map<String, List<User>> userJdk7Map = new HashMap<String, List<User>>();
        //按照名字分组
        for (User u : userList) {
            if (userJdk7Map.containsKey(u.getName())) {//如果map中已经存在则add 到groupList中
                List<User> groupTempUserList = userJdk7Map.get(u.getName());
                groupTempUserList.add(u);
            }else{//增加一个新的
                List<User> groupTempUserList = new ArrayList<User>();
                groupTempUserList.add(u);
                userJdk7Map.put(u.getName(), groupTempUserList);
            }
        }

        //按照密码分组 大写略 参考名字分组

        //jdk7 打印
        for (Map.Entry<String, List<User>> entry : userJdk7Map.entrySet()) {
            System.out.println("---------------- jdk7 group by user name = " + entry.getKey() + "----------");
            for (User user : entry.getValue()) {
                System.out.println( user.getPassword());
            }
        }

    }

    /**
     * 构造一个用户列表
     * @return
     */
    private static List<User> constructUserList() {
        List<User> userList = new ArrayList<User>();
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 2; j++) {
                User u = new User();
                u.setPassword("password" + j);
                u.setName("name" + i);
                userList.add(u);
            }
        }
        return userList;
    }
}


运行结果:

---------------- group by user name = name1----------
password0
password1
---------------- group by user name = name0----------
password0
password1
----------------  group by user password = password0----------
name0
name1
----------------  group by user password = password1----------
name0
name1
---------------- jdk7 group by user name = name1----------
password0
password1
---------------- jdk7 group by user name = name0----------
password0
password1

如果感兴趣,可以点击进Collectors.groupingBy看看,参数就是一个Function,根据条件进行分组。

##2. 最经常使用的,集合转变成其他集合

public class Jdk8_collector_reduce_test {

    private static class User {
        private String name;
        private String password;
        //getter setter
    }

    public static void main(String[] args) {
        List<User> userList = constructUserList();

        //使用JDK8 提取所有名字
        List<String> userStrList = userList.stream().map(User::getName).collect(Collectors.toList());
        //把名字提取出来,并转化成name set
        Set<String> userNameSet = userList.stream().map(User::getName).collect(Collectors.toSet());

        //转化成<name, password> 结构的map,注意: key 不能重复,使用distinct去重复
        Map<String, String> userNameMap = userList.stream().distinct().collect(Collectors.toMap(u -> u.getName(), u -> u.getPassword()));

        //提取成 Map<name, User>
        Map<String, User> userMap = userList.stream().distinct().collect(Collectors.toMap(u -> u.getName(), Function.identity()));

        //提取成 Map<name, String> 合并
        Map<String, String> userMergeDulicateMap = userList.stream()
                .collect(Collectors.toMap(User::getName, User::getPassword, (t1, t2) ->{
                    return t1 + "," + t2;
                }));
        
        System.out.println("---------------打印 list -------------");
        userStrList.forEach(System.out::println);

        System.out.println("---------------打印 set -------------");
        userNameSet.forEach(System.out::println);

        System.out.println("---------------打印 map -------------");
        userNameMap.forEach((key, val) -> {
            System.out.println(key + "---" + val);
        });

        System.out.println("---------------打印 user map -------------");
        userMap.forEach((key, val) -> {
            System.out.println(key + "---" + val.getPassword());
        });

        System.out.println("---------------打印 userMergeDulicateMap -------------");
        userMergeDulicateMap.forEach((key, val) -> {
            System.out.println(key + "---" + val);
        });

    }

    /**
     * 构造一个用户列表
     *
     * @return
     */
    private static List<User> constructUserList() {
        List<User> userList = new ArrayList<User>();
        for (int i = 0; i < 4; i++) {
            User u = new User();
            u.setPassword("password" + i);
            u.setName("name" + i);
            userList.add(u);
            userList.add(u);
        }
        return userList;
    }
}

运行结果:

---------------打印 list -------------
name0
name0
name1
name1
name2
name2
name3
name3
---------------打印 set -------------
name3
name2
name1
name0
---------------打印 map -------------
name3---password3
name2---password2
name1---password1
name0---password0
---------------打印 user map -------------
name3---password3
name2---password2
name1---password1
name0---password0
---------------打印 userMergeDulicateMap -------------
name3---password3,password3
name2---password2,password2
name1---password1,password1
name0---password0,password0

##3. Collectors API使用

下面例子介绍部分collectors API的使用,主要有:maxBy、joining、counting、summingInt、partitioningBy、summarizingInt 的使用,如果感兴趣可以琢磨一下collectors API的内部使用,理解一下downstream ,和前面章节介绍的 predicate、function、consumer 就很容易融入到自己代码中.

public class Jdk8_collector_operation_test {

    private static class User {
        private String name;
        private String password;

       	//省略getter setter
    }

    public static void main(String[] args) {
        List<User> userList = constructUserList();

        //1.maxBy求最大值
        User user = userList.stream().collect(Collectors.collectingAndThen(
                Collectors.maxBy((t1, t2) ->t1.getPassword().length() - t2.getPassword().length()), Optional::get));

        //2.joining 合并,通过分隔符“,”合并用户名称
        String userName = userList.stream().map(User::getName).collect(Collectors.joining(","));

        //3.summingInt 统计总和
        int totalNameLen = userList.stream().map(User::getName).collect(Collectors.summingInt(String::length));

        //4.counting 集合个数
        Long count = userList.stream().map(User::getName).collect(Collectors.counting());

        //5.groupingBy 分组, counting统计元素个数,按照名字分组,并统计分组元素个数
        Map<String, Long> groupNameCount = userList.stream().collect(Collectors.groupingBy(User::getName, Collectors.counting()));

        //6.partitioningBy 分片 根据Predicate条件分片
        Map<Boolean, List<User>> partitioningMap = userList.stream()
                .collect(Collectors.partitioningBy(u -> u.getPassword().indexOf("1") >= 0, Collectors.toList()));

        //7.summarizingInt 对数据的汇总统计 返回一个统计类IntSummaryStatistics
        IntSummaryStatistics intSummaryStatistics = userList.stream().map(User::getPassword)
                .collect(Collectors.summarizingInt(String::length));


        System.out.println( "password最大长度的:" + user.getName());
        System.out.println("所用用户名:" + userName);
        System.out.println("所有用户名长度:" + totalNameLen);
        System.out.println("集合个数:" + count);
        groupNameCount.forEach((key, val) -> {
            System.out.println(key + " ---打印分组元素个数--- " + val);
        });

        partitioningMap.forEach((key, val) -> {
            System.out.println(key + " ---打印分片元素--- ");
            val.forEach(u -> {
                System.out.println( u.getName() );
            });
        });

        System.out.println("------汇总统计----平均值:" + intSummaryStatistics.getAverage());
        System.out.println("------汇总统计----元素个数:" + intSummaryStatistics.getCount());
        System.out.println("------汇总统计----最小值:" + intSummaryStatistics.getMin());
        System.out.println("------汇总统计----最大值:" + intSummaryStatistics.getMax());
        System.out.println("------汇总统计----累加:" + intSummaryStatistics.getSum());

    }

    /**
     * 构造一个用户列表
     *
     * @return
     */
    private static List<User> constructUserList() {
        List<User> userList = new ArrayList<User>();
        for (int i = 0; i < 4; i++) {
            User u = new User();
            u.setPassword("password" + i);
            u.setName("name" + i);
            userList.add(u);
            userList.add(u);
        }
        return userList;
    }
}

返回结果:

password最大长度的:name0
所用用户名:name0,name0,name1,name1,name2,name2,name3,name3
所有用户名长度:40
集合个数:8
name3 ---打印分组元素个数--- 2
name2 ---打印分组元素个数--- 2
name1 ---打印分组元素个数--- 2
name0 ---打印分组元素个数--- 2
false ---打印分片元素--- 
name0
name0
name2
name2
name3
name3
true ---打印分片元素--- 
name1
name1
------汇总统计----平均值:9.0
------汇总统计----元素个数:8
------汇总统计----最小值:9
------汇总统计----最大值:9
------汇总统计----累加:72

JDK8 API使用很多时候耐心点看就能明白作者这样设计的巧妙,还是要多用,即使一开始不熟悉,用起来很别扭,应该用着用着就爱上了。

转载于:https://my.oschina.net/kaishui/blog/754915


http://www.niftyadmin.cn/n/2001453.html

相关文章

搭建一个Tomcat,作为图片服务器,异步上传图片

1.图片服务器Tomcat的设置 tomcat/conf/web.xml中内容更改,将tomcat设置为可以读写<servlet><servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class><init-param><…

数据库sql优化经验总结

2019独角兽企业重金招聘Python工程师标准>>> 数据库sql优化经验总结 1.sql语句用索引&#xff0c;先聚集&#xff0c;后非聚集 sql语句查询中&#xff0c;能够使用聚集索引&#xff0c;就将聚集索引查询条件放最前面,然后是对应的非聚集索引 2.游标的用法 游标的快慢…

记一次失误造成的影响

在使用salt给机器添加时间同步的计划任务的时候&#xff0c;忘记salt的cron模块的写法了&#xff0c;于是偷懒直接使用echo追加到/var/spool/cron/root的方法添加了计划任务。如下&#xff1a;salt * cmd.run "echo */10 * * * /usr/sbin/ntpdate ntp1.aliyun.com > /d…

MR Technology Equipment Hololens Application Exhibition and Exchange

During the Microsoft Education Products Tour held in Nanjing on December 8, 2018, as a booth demonstrator, I demonstrated the application of MR technology equipment Hololens in the field of education for guests.

JavaSE_01概述

1. encoding [nkd] n. [计] 编码; v. [计] 编码encode的ing形式 2. applet [plt] n. 支程序小应用程序小型程式程序类型 3. algorithm [lgr()m] n. [计][数] 算法运算法则 4. application [plke()n] n. 应用申请应用程序敷用 5. assert [st] vt. 维护坚持断言主张声称 6. comma…

Filming of Microsoft China's Promotional Film The Application of Hololens in Education

On June 29, 2019, as the keynote speaker and main demonstrator, I participated in the filming of Microsoft China’s “Hololens in the field of education” promotional film. I demonstrated the characteristics of using Hololens for classroom teaching, record…

Run .NET Core on your platform

2019独角兽企业重金招聘Python工程师标准>>> 配置.Net可以运行于Mac os x或Linux等系统的方法 https://www.microsoft.com/net/core#macos 转载于:https://my.oschina.net/swingcoder/blog/757590

Hololens Application Sharing Conference (10 August 2019)

On August 10, 2019, I was invited to attend the exhibition of Microsoft products in Fujian education field. At the exhibition, I gave a demonstration of MR related equipment and showed how to use MR equipment in front-line teaching.