使用流Java 8或在SQL中以最佳的方式对类进行分组 [英] Grouping a class using stream java 8 or in SQL whichever is best

查看:91
本文介绍了使用流Java 8或在SQL中以最佳的方式对类进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数据是这样的

    head child assigned total
[   Mas   Mas1     2    5
,   Mas   Mas2     0    5
,   Usr   usr1     4    4
,   Usr   usr2     1    3
,   Inv   Inv1     3    5
,   Inv   Inv2     2    3
,   Inv   Inv3     2    3
,   Inv   Inv4     1    3
]

我想要他们的孩子的总和作为特定的标头.

I want sum of their child for a particular header.

我在sql中使用分区

select head,
SUM(childAssigned) over (partition by am.acl_group) as assignedHead,
sum(childTotal) over (partition by am.acl_group) as totalHead,
child,
childAssigned,
childTotal

由于HQL astquerytranslatorfactory不支持分区依据",因此我将其用作本机查询

Since, "partition by" is not supported by HQL astquerytranslatorfactory, I am using this as a native query

我有一个持有SQL响应的类

I have a class which is holding SQL Response

class AclList{
    String head;
    Integer assignedHead;
    Integer totalHead;
    String child;
    Integer assignedChild;
    Integer totalChild;
}

数据是这样的

[   Mas 2   10  Mas1    2   5
,   Mas 2   10  Mas2    0   5
,   Usr 5   7   usr1    4   4
,   Usr 5   7   usr2    1   3
,   Inv 8   14  Inv1    3   5
,   Inv 8   14  Inv2    2   3
,   Inv 8   14  Inv3    2   3
,   Inv 8   14  Inv4    1   3
]

我想要一个将相同标题的子项分组的响应.

I want a response which will groupify child of same header.

响应应该类似于ResponseClass(类型,已分配,总计,列表)

Response should be like ResponseClass(type, assigned, total, List)

[ 
  { 
    "type":"MAS",
    "assigned":"2",
    "total":"10",
    "subType":[ 
      { 
        "type":"MAS1",
        "assigned":"2",
        "total":"5"
      },
      { 
        "type":"MAS2",
        "assigned":"0",
        "total":"5"
      }
    ]
  },
  { 
    "type":"USR",
    "assigned":"5",
    "total":"7",
    "subType":[ 
      { 
        "type":"USR1",
        "assigned":"4",
        "total":"4"
      },
      { 
        "type":"USR2",
        "assigned":"1",
        "total":"3"
      }
    ]
  }
]

类详细信息(类型,已分配,总计) 我的方法是将标题保留在hashmap的键中,将子元素保留在hashmap的值中 由于一个头部的所有三列都相同,所以等于,哈希码要小心.

class Details(type, assigned, total) My approach is keeping header in hashmap's key, child in hashmap's value Since all 3 columns of a head are same, So, equals, hashcode take care.

ChildDetails类(列表) 哈希图

class ChildDetails(List) HashMap

Iterate sql response
if hashmap.contains(head) //exist
    fetch value, add new one in list
    hashmap.put(head, updated)
else
    create header,
    create child, add it to a blank list
    hashmap.put(head, new list)

再次迭代hashmap,将其安排在新的json响应中

Again iterate hashmap, arrange it in new json response

但是,这是一个繁琐的过程&;效率低下.

But, this is a cumbersome proces & inefficient.

反正可以用JAVA stream()完成吗?

Is there anyway it can be done with JAVA stream() ?

推荐答案

是的,可以使用JAVA stream()

package com.bbc.enums;

import lombok.*;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.*;
import java.util.stream.Collectors;


public class StackOverFlow {
    public static void main(String[] args) {
        List<AclList> aclLists = Arrays.asList(
                new AclList("Mas", 2, 10, "Mas1", 2, 5),
                new AclList("Mas", 2, 10, "Mas2", 0, 5),
                new AclList("USR", 5, 7, "USR1", 4, 4),
                new AclList("USR", 5, 7, "USR2", 1, 3),
                new AclList("Inv", 8, 14, "Inv1", 3, 5),
                new AclList("Inv", 8, 14, "Inv2", 2, 3),
                new AclList("Inv", 8, 14, "Inv3", 2, 3),
                new AclList("Inv", 8, 14, "Inv4", 1, 3)

        );

        Map<String, Map<Integer, Map<Integer, List<AclList>>>> collect = aclLists.stream()
                .collect(Collectors.groupingBy(AclList::getHead, Collectors.groupingBy(AclList::getAssignedHead,
                        Collectors.groupingBy(AclList::getTotalHead))));

        List<HashMap<String, Object>> resList = new ArrayList<>();
        collect.forEach((k1, v1) -> {
            HashMap<String, Object> res = new HashMap<>();
            res.put("type", k1);
            v1.forEach((k2, v2) -> {
                res.put("assigned", k2);
                v2.forEach((k3, v3) -> {
                    res.put("total", k3);
                    List<HashMap<String, Object>> list = new ArrayList<>();
                    v3.forEach(aclList -> {
                        HashMap<String, Object> map1 = new HashMap<>();
                        map1.put("type", aclList.getChild());
                        map1.put("assigned", aclList.getAssignedChild());
                        map1.put("total", aclList.getTotalChild());
                        list.add(map1);
                    });
                    res.put("subType", list);
                });
            });
            resList.add(res);
        });
        System.out.println(resList);
        // if you want json response then
        System.out.println(listmap_to_json_string(resList));
    }


    public static String listmap_to_json_string(List<HashMap<String, Object>> list) {
        JSONArray json_arr = new JSONArray();
        for (Map<String, Object> map : list) {
            JSONObject json_obj = new JSONObject();
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                try {
                    json_obj.put(key, value);
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            json_arr.put(json_obj);
        }
        return json_arr.toString();
    }
}


@AllArgsConstructor
@Getter
@Setter
@ToString
@NoArgsConstructor
class AclList {
    String head;
    Integer assignedHead;
    Integer totalHead;
    String child;
    Integer assignedChild;
    Integer totalChild;
}

这篇关于使用流Java 8或在SQL中以最佳的方式对类进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆