使用流Java 8或在SQL中以最佳的方式对类进行分组 [英] Grouping a class using stream java 8 or in SQL whichever is best
问题描述
数据是这样的
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屋!