JDK8 Collectors 使用篇(四)
博客专区 > kaishui 的博客 > 博客详情
JDK8 Collectors 使用篇(四)
kaishui 发表于1年前
JDK8 Collectors 使用篇(四)
  • 发表于 1年前
  • 阅读 99
  • 收藏 1
  • 点赞 0
  • 评论 0

华为云·免费上云实践>>>   

摘要: Collectors是JDK8加入的一个重量级功能,对于集合的操作更加简单容易得到我们想要的,简单的一种集合到另外一种集合类型的转换,做reduce操作,和根据不同需要分组、分片、统计,collectors都不会让人失望。

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

共有 人打赏支持
粉丝 48
博文 7
码字总数 6812
×
kaishui
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: