文档章节

JDK8 Collectors 使用篇(四)

kaishui
 kaishui
发布于 2016/10/07 15:20
字数 1401
阅读 142
收藏 1
点赞 0
评论 0

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

© 著作权归作者所有

共有 人打赏支持
kaishui
粉丝 49
博文 12
码字总数 10711
作品 0
广州
程序员
JDK8 Stream 从入门到装逼(三)

在lambdas中,可以看到lambda表达式让代码更加简洁、干净、容易理解,并允许不需要创建一个类就可以达到目的。lambdas很好的帮助开发人员更好的表达片段代码的意思,Stream对于集合提供一个抽...

kaishui ⋅ 2016/09/06 ⋅ 11

java8函数式编程--收集器collector

java8的stream api能很方便我们对数据进行统计分类等工作,以前我们写的很多统计数据的代码往往是循环迭代得到的,不说别人看不懂,自己的代码放久了也要重新看一段时间才能看得懂。现在,j...

JoshuaShaw ⋅ 2015/08/04 ⋅ 2

Java 8 - From PermGen to Metaspace

Java 8 - From PermGen to Metaspace http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html http://ifeve.com/java-permgen-removed/ https://blogs.oracle.com/poonam/abo......

秋风醉了 ⋅ 2014/10/26 ⋅ 0

java8-lambda实战

前言 java8推出已经很久了,然而其新特性却几乎没有怎么用过。原因是既然已有的只是满足需求何必去学习新的?然而,随着敲代码越来越多,业务上有很多臃肿繁琐的判断校验之类的代码,使得代码...

RyanMiao ⋅ 2016/11/20 ⋅ 0

【Java入门提高篇】Day21 容器类详解(四)ArrayList源码分析

今天要介绍的是List接口中最常用的实现类——ArrayList,本篇的源码分析基于JDK8,如果有不一致的地方,可先切换到JDK8后再进行操作。 本篇的内容主要包括这几块: 1.源码结构介绍 2.源代码展...

MFrank ⋅ 06/04 ⋅ 0

java8 list转map

List转Map List转Map() List转Map List转Map> doc Ignore duplicates when producing map using streams...

go4it ⋅ 2016/11/09 ⋅ 0

spring 4 升级踩雷指南

前言 最近,一直在为公司老项目做核心库升级工作。本来只是想升级一下 JDK8 ,却因为兼容性问题而不得不升级一些其他的库,而其他库本身依赖的一些库可能也要同步升级。这是一系列连锁问题,...

静默虚空 ⋅ 2017/12/15 ⋅ 0

探究Java的ConcurrentHashMap实现机制

原文地址: http://blog.csdn.net/u011080472/article/details/51392712 在学习ConcurrentHashMap的高并发时,找到了一些高质量的博客,就没有重复转载了。分别列出了JDK6中的Segment分段加锁...

Gavin__Zhou ⋅ 2017/08/06 ⋅ 0

java8 使用Map中的computeIfAbsent方法构建本地缓存,提高程序效率

一、概念及使用介绍 在JAVA8的Map接口中,增加了一个方法computeIfAbsent,此方法签名如下: public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) Map接口的......

cloud-coder ⋅ 2014/04/04 ⋅ 0

监控系统 scollector 采集器

Command scollector Scollector is a metric collection agent for OpenTSDB 2.0 and Bosun. tcollector (https://github.com/OpenTSDB/tcollector) is OpenTSDB's data collection framewor......

MtrS ⋅ 2016/07/01 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

6. Shell 函数 和 定向输出

Shell 常用函数 简洁:目前没怎么在Shell 脚本中使用过函数,哈哈,不过,以后可能会用。就像java8的函数式编程,以后获取会用吧,行吧,那咱们简单的看一下具体的使用 Shell函数格式 linux ...

AHUSKY ⋅ 3分钟前 ⋅ 0

MySQL 内核深度优化

MYSQL数据库适用场景广泛,相较于Oracle、DB2性价比更高,Web网站、日志系统、数据仓库等场景都有MYSQL用武之地,但是也存在对于事务性支持不太好(MySQL 5.5版本开始默认引擎才是InnoDB事务...

OSC_cnhwTY ⋅ 10分钟前 ⋅ 0

单片机软件定时器

之前写了一个软件定时器,发现不够优化,和友好,现在重写了 soft_timer.h #ifndef _SOFT_TIMER_H_#define _SOFT_TIMER_H_#include "sys.h"typedef void (*timer_callback_function)(vo...

猎人嘻嘻哈哈的 ⋅ 12分钟前 ⋅ 0

好的资料搜说引擎

鸠摩搜书 简介:鸠摩搜书是一个电子书搜索引擎。它汇集了多个网盘和电子书平台的资源,真所谓大而全。而且它还支持筛选txt,pdf,mobi,epub、azw3格式文件。还显示来自不同网站的资源。对了,...

乔三爷 ⋅ 21分钟前 ⋅ 0

Debian下安装PostgreSQL的表分区插件pg_pathman

先安装基础的编译环境 apt-get install build-essential libssl1.0-dev libkrb5-dev 将pg的bin目录加入环境变量,主要是要使用 pg_config export PATH=$PATH:/usr/lib/postgresql/10/bin 进......

玛雅牛 ⋅ 21分钟前 ⋅ 0

inno安装

#define MyAppName "HoldChipEngin" #define MyAppVersion "1.0" #define MyAppPublisher "Hold Chip, Inc." #define MyAppURL "http://www.holdchip.com/" #define MyAppExeName "HoldChipE......

backtrackx ⋅ 51分钟前 ⋅ 0

Linux(CentOS)下配置php运行环境及nginx解析php

【part1:搭建php环境】 1.选在自己需要安装的安装包版本,wget命令下载到服务器响应目录 http://php.net/releases/ 2.解压安装包 tar zxf php-x.x.x 3.cd到解压目录执行如下操作 cd ../php-...

硅谷课堂 ⋅ 57分钟前 ⋅ 0

Nginx服务架构初探(四):nginx服务器的rewrite功能

nginx服务器的rewrite功能 1.nginx后端服务器组的配置 1>upstream name {…} name是给服务器组限的组名 2>server address [parameters]; address为服务器地址 parame......

余温灬未存 ⋅ 今天 ⋅ 0

layer.prompt使文本框为空的情况下也能点击确定

最近一直在使用layui,但是用到弹出层layer.prompt时,如果文本框是空的话点击确定没有反应,不能向下执行。 但是我又需要空值,看看我原来的代码。 123456789 layer.prompt...

孟飞阳 ⋅ 今天 ⋅ 0

Linux普通文件压缩工具gzip、Bzip2、xz

第六章 文件压缩和打包 6.1 压缩打包介绍 Linux环境常见压缩文件类型: .zip,.gz,.bz2,.xz, .tar.gz,.tar.bz2,.tar.xz 压缩打包的目的 方便文件传输 节省磁盘空间 减少传输花费的时间 ...

弓正 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部