Data columns look like :
CompanyId,Parent Id
1,1
2,1
3,1
4,2
5,2
each company belongs to some parent. My need to is convert this raw data into below json format.
[
{
id : 1
child : [
{
id : 2
child : [
{
id : 4
},
{
id : 5
}
]
},
{
id : 3
}
]
}
]
any java code implementation will be helpful.
Assuming the data table looks like this:
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);
We can create a parent to children map:
Map<Integer, List<Integer>> parentToChildren = childToParent.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
For simplicity, let's create a Company
class likewise:
@Data
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Company {
private final int id;
@JsonProperty(value = "child")
private List<Company> children;
}
Then create Company
objects:
Map<Integer, Company> idToCompany = childToParent.keySet().stream()
.map(integer -> new Company(integer, null))
.collect(Collectors.toMap(Company::getId, company -> company));
And now we can set the children for each parent:
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);
}
});
Now we can extract the "head" companies like this:
List<Company> companiesHeads = childToParent.entrySet().stream()
.filter(childIdToParentId -> childIdToParentId.getKey().equals(childIdToParentId.getValue()))
.map(Map.Entry::getKey)
.map(idToCompany::get)
.collect(Collectors.toList());
And print to the screen in JSON format:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(mapper.writeValueAsString(companiesHeads));
Output:
[ {
"id" : 1,
"child" : [ {
"id" : 2,
"child" : [ {
"id" : 4
}, {
"id" : 5
} ]
}, {
"id" : 3
} ]
} ]