Java8新特性-分组groupingBy-实战(三)

利用Java8 StreamAPI完成项目需求

需求

将一批数据转换成页面的格式,如下 表格1

IP 类型 次数
172.12.12.1 QQ 2
172.12.12.2 微信 1
172.12.12.2 QQ 2
public class Demo2 {

    public static class  ImageItem{

        private String id ;

        private String type ;

        private String ip ;

        private String account ;

        public ImageItem(String id, String type, String ip, String account) {
            this.id = id;
            this.type = type;
            this.ip = ip;
            this.account = account;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getIp() {
            return ip;
        }

        public void setIp(String ip) {
            this.ip = ip;
        }

        public String getAccount() {
            return account;
        }

        public void setAccount(String account) {
            this.account = account;
        }
    }

    public static void main(String[] args) {
        List imageList = new ArrayList<>();
        ImageItem item1 = new ImageItem("1","微信","172.12.12.1","13912911111");
        imageList.add(item1);


        ImageItem item2 = new ImageItem("2","微信","172.12.12.1","13912911111");
        imageList.add(item2);

        ImageItem item3 = new ImageItem("3","QQ","172.12.12.2","13912911111");
        imageList.add(item3);

        ImageItem item4 = new ImageItem("4","QQ","172.12.12.2","13912922222");
        imageList.add(item4);

        ImageItem item5 = new ImageItem("5","微信","172.12.12.2","13912922222");
        imageList.add(item5);

        List result = multiGroup(imageList);

        result.forEach(System.out::println);


    }

    public static List multiGroup(List imageList){
        Map> res = imageList.stream()
                //先根据ip分组,再进行类型分组
                .collect(groupingBy(ImageItem::getIp, groupingBy(ImageItem::getType, counting())));
        List result = new ArrayList<>();
        res.forEach((ip, valueMap) -> {
            valueMap.forEach((type, time) -> {
                String singleRes = "ip:" + ip + "通过" + type + "发送了" + time + "次";
                result.add(singleRes);
            });
        });
        return result;
}

打印结果:

ip:172.12.12.2通过QQ发送了2次
ip:172.12.12.2通过微信发送了1次
ip:172.12.12.1通过微信发送了2次

方法优化

由于业务需求多变,现在需要变换统计维度,如想做成下面的 表格2 效果:

账号 类型 次数
13912922222 QQ 1
13912922222 微信 1
13912911111 QQ 1
13912911111 微信 2

虽然再歇一个方法也是OK的 但是你会发现到处都是重复的逻辑,真正需要修改的就是第一次分组的逻辑

那就修改multiGroup方法,让调用方自己把分组的逻辑传给我吧,多传入一个Function

public static List<String> multiGroup(List<ImageItem> imageList, Function<ImageItem, String> function) {
        Map<String, Map<String, Long>> res = imageList.stream()
                //先根据ip分组,再进行类型分组
                .collect(groupingBy(function, groupingBy(ImageItem::getType, counting())));
        List<String> result = new ArrayList<>();
        res.forEach((ip, valueMap) -> {
            valueMap.forEach((type, time) -> {
                String singleRes = "ip:" + ip + "通过" + type + "发送了" + time + "次";
                result.add(singleRes);
            });
        });
        return result;
    }

调用代码

List<String> result = multiGroup(imageList, ImageItem::getAccount);//表格2效果的调用
List<String> result = multiGroup(imageList, ImageItem::getIp);//表格1效果的调用

你可能感兴趣的:(Java8新特性)