java - 从 Java Hashmap 生成树结构
问题描述
我目前有一个具有多个属性的类,这些属性描述了我系统中某种类型的对象。这个类被称为EnrollmentInfo
.
我还有一个结构如下的哈希图;
HashMap<EnrolmentInfo, List<EnrolmentInfo>> devices = new HashMap<>();
可以看出,这个 hashmap 中的 value 属性包含一个 EnrollmentInfo 类类型的 ArrayList。为了提供一些上下文,此哈希图用于将树结构的父节点和关联的子节点保存为键值对。
我通过遍历并从子/父表中提取详细信息来生成此哈希图,如下所示:
Child : Parent
1 : 0
2 : 0
3 : 2
4 : 0
5 : 4
6 : 4
7 : 1
8 : 6
提取父母和孩子并放入HashMap的代码如下:
// Extracts the parents and assigns them to the key values
for (EnrolmentInfo enrolmentInfo : enrolmentInfos) {
Integer nodeParentId = enrolmentInfo.getParentId();
EnrolmentInfo parentEnrolmentInfo = dms.getDevice(nodeParentId).getEnrolmentInfo();
devices.put(parentEnrolmentInfo, new ArrayList<EnrolmentInfo>());
}
// Extracts the children and assigns them to the children arraylist of each associated parent.
for (EnrolmentInfo enrolmentInfo : enrolmentInfos) {
int nodeId = enrolmentInfo.getId();
Integer parentId = enrolmentInfo.getParentId();
EnrolmentInfo nodeEnrolmentInfo = dms.getDevice(nodeId).getEnrolmentInfo();
for (Map.Entry<EnrolmentInfo, List<EnrolmentInfo>> parentDevice : devices.entrySet()) {
if (parentDevice.getKey().getId() == parentId) {
parentDevice.getValue().add(nodeEnrolmentInfo);
break;
}
}
}
我现在的问题是将这个 hashmap 组合成一个实际的树结构,以便它可以通过 JSON 库编译成人类可读的形式。
更具体地说,如何根据上面提到的 HashMap 生成嵌套树结构?
编辑:下面显示的是我最后期望的那种 JSON 格式的示例结构。
{
"id" : 0,
"children" : [
{
"id" : 1,
"children" : [
{
"id" : 7,
"children" : []
}
]
},
{
"id" : 2,
"children" : [
{
"id" : 3,
"children" : []
}
]
},
{
"id" : 4,
"children" : [
{
"id" : 5,
"children" : []
},
{
"id" : 6,
"children" : [
{
"id" : 8,
"children" : []
}
]
}
]
}
]
}
编辑:到目前为止,我已经创建了一个 bean 类,如下所示:
public class DeviceHierarchyNode implements Serializable {
@ApiModelProperty(name = "id", value = "ID of the node generated. Same as Device ID",
required = true)
private int id;
@ApiModelProperty(name = "label", value = "Device name as suggested by the user.",
required = true)
private String label;
@ApiModelProperty(name = "children", value = "List of child devices associated with device if any",
required = true)
private List<DeviceHierarchyNode> children;
我的计划是使用它来创建最终的嵌套结构。
解决方案
警告:hacky。
您能否创建一个包装底层的节点类型:
public class EnrolmentInfoNode {
private EnrolmentInfo info;
private List<EnrolmentInfoNode> children;
public EnrolmentInfoNode(EnrolmentInfo contents) {
this.info = contents;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + info.getId();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EnrolmentInfoNode other = (EnrolmentInfoNode) obj;
if (info.getId() != other.info.getId())
return false;
return true;
}
public void addChild(EnrolmentInfoNode child) {
if (children == null) {
children = new ArrayList<>();
}
children.add(child);
}
}
然后重新映射:
Map<EnrolmentInfo, EnrolmentInfoNode> nodeMap = new HashMap<>();
for (Entry<EnrolmentInfo, List<EnrolmentInfo>> entry : map.entrySet()) {
for (EnrolmentInfo child : entry.getValue()) {
EnrolmentInfoNode childNode = nodeMap.computeIfAbsent(child, EnrolmentInfoNode::new);
nodeMap.computeIfAbsent(entry.getKey(), EnrolmentInfoNode::new)
.addChild(childNode);
}
}
假设您知道节点 0 是父节点:
String json = new GsonBuilder().setPrettyPrinting()
.create()
.toJson(nodeMap.get(enrolmentInfo0));
System.out.println(json);
如果不这样做,您可以向 中添加“parentNode”字段EnrolmentInfoNode
,然后扫描节点映射以找到第一个具有空父节点(因此是根节点)的节点,然后您就可以参加比赛了。
推荐阅读
- javascript - Javascript CLI:如何调用 bin 文件以便我可以使用 Jest 运行集成测试
- html - 如何让div内容占据100%的高度
- javascript - 如何停止吹扫顺风组件
- modeling - 建模和识别曲线
- python-3.x - 如何使用python将“存储为文本的数字”转换为.xls中的“数字”
- vba - 通过多个过滤器过滤访问表单
- ios - UIDocumentPickerViewController 以阿拉伯语显示翻转的内容
- git-bash - git bash终端在使用mongoDB时覆盖文本
- java - Springboot 在 Eureka 客户端依赖项上运行失败
- python - 试图制作一个在用户输入时停止的循环