Генерация древовидной структуры из Java Hashmap - PullRequest
0 голосов
/ 22 марта 2019

В настоящее время у меня есть класс с несколькими атрибутами, описывающими определенный тип объекта в моей системе.Этот класс известен как EnrollmentInfo.

. У меня также есть хэш-карта, которая имеет следующую структуру:

HashMap<EnrolmentInfo, List<EnrolmentInfo>> devices = new HashMap<>();

Как видно, свойства значений в этом хэш-файле содержат ArrayListтипа класса EnrollmentInfo.Для обеспечения некоторого контекста эта хэш-карта используется для хранения родительских узлов и связанных дочерних узлов древовидной структуры в качестве пар «ключ-значение».

Я сгенерировал эту хэш-карту, просматривая и извлекая детали из дочерней / родительской таблицы, напримерследующим образом:

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;
                }
            }
        }

Теперь моя задача состоит в том, чтобы составить эту хэш-карту вфактическая древовидная структура, так что она может быть скомпилирована в удобочитаемую форму с помощью библиотеки 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;

Я планирую использовать это для создания окончательной вложенной структуры.

1 Ответ

1 голос
/ 22 марта 2019

Предупреждение: 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, а затем отсканировать карту узла, чтобы найти первое, которое имеетнулевой родитель (следовательно, корень), и вы отправляетесь в гонки.

...