从父子 ID 的原始数据创建 Json 层次结构
Create Json Hierarchy from from raw data of parent child id
数据列看起来像:
CompanyId,Parent Id
1,1
2,1
3,1
4,2
5,2
每家公司都属于某个母公司。我需要将此原始数据转换为以下 json 格式。
[
{
id : 1
child : [
{
id : 2
child : [
{
id : 4
},
{
id : 5
}
]
},
{
id : 3
}
]
}
]
任何 java 代码实施都会有所帮助。
假设数据 table 如下所示:
Map<Integer, Integer> childToParent = new HashMap<>();
childToParent.put(1, 1);
childToParent.put(2, 1);
childToParent.put(3, 1);
childToParent.put(4, 2);
childToParent.put(5, 2);
我们可以创建一个 parent 到 children 映射:
Map<Integer, List<Integer>> parentToChildren = childToParent.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
为简单起见,我们同样创建一个Company
class:
@Data
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Company {
private final int id;
@JsonProperty(value = "child")
private List<Company> children;
}
然后创建Company
objects:
Map<Integer, Company> idToCompany = childToParent.keySet().stream()
.map(integer -> new Company(integer, null))
.collect(Collectors.toMap(Company::getId, company -> company));
现在我们可以为每个 parent:
设置 children
idToCompany.values().forEach(company -> {
List<Integer> childrenIds = parentToChildren.get(company.getId());
if(childrenIds != null){
List<Company> children = childrenIds.stream()
.filter(childId -> childId != company.getId()) // a company can't be a parent of itself
.map(idToCompany::get)
.collect(Collectors.toList());
company.setChildren(children);
}
});
现在我们可以像这样提取“头部”公司:
List<Company> companiesHeads = childToParent.entrySet().stream()
.filter(childIdToParentId -> childIdToParentId.getKey().equals(childIdToParentId.getValue()))
.map(Map.Entry::getKey)
.map(idToCompany::get)
.collect(Collectors.toList());
并以 JSON 格式打印到屏幕:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(mapper.writeValueAsString(companiesHeads));
输出:
[ {
"id" : 1,
"child" : [ {
"id" : 2,
"child" : [ {
"id" : 4
}, {
"id" : 5
} ]
}, {
"id" : 3
} ]
} ]
数据列看起来像:
CompanyId,Parent Id
1,1
2,1
3,1
4,2
5,2
每家公司都属于某个母公司。我需要将此原始数据转换为以下 json 格式。
[
{
id : 1
child : [
{
id : 2
child : [
{
id : 4
},
{
id : 5
}
]
},
{
id : 3
}
]
}
]
任何 java 代码实施都会有所帮助。
假设数据 table 如下所示:
Map<Integer, Integer> childToParent = new HashMap<>();
childToParent.put(1, 1);
childToParent.put(2, 1);
childToParent.put(3, 1);
childToParent.put(4, 2);
childToParent.put(5, 2);
我们可以创建一个 parent 到 children 映射:
Map<Integer, List<Integer>> parentToChildren = childToParent.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
为简单起见,我们同样创建一个Company
class:
@Data
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Company {
private final int id;
@JsonProperty(value = "child")
private List<Company> children;
}
然后创建Company
objects:
Map<Integer, Company> idToCompany = childToParent.keySet().stream()
.map(integer -> new Company(integer, null))
.collect(Collectors.toMap(Company::getId, company -> company));
现在我们可以为每个 parent:
设置 childrenidToCompany.values().forEach(company -> {
List<Integer> childrenIds = parentToChildren.get(company.getId());
if(childrenIds != null){
List<Company> children = childrenIds.stream()
.filter(childId -> childId != company.getId()) // a company can't be a parent of itself
.map(idToCompany::get)
.collect(Collectors.toList());
company.setChildren(children);
}
});
现在我们可以像这样提取“头部”公司:
List<Company> companiesHeads = childToParent.entrySet().stream()
.filter(childIdToParentId -> childIdToParentId.getKey().equals(childIdToParentId.getValue()))
.map(Map.Entry::getKey)
.map(idToCompany::get)
.collect(Collectors.toList());
并以 JSON 格式打印到屏幕:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(mapper.writeValueAsString(companiesHeads));
输出:
[ {
"id" : 1,
"child" : [ {
"id" : 2,
"child" : [ {
"id" : 4
}, {
"id" : 5
} ]
}, {
"id" : 3
} ]
} ]