java无序构建组织树

本文介绍了如何使用Java构建无序组织树。通过遍历节点并判断新增节点是否为现有节点的子节点来构建树结构,过程中涉及节点的移动、增加和删除,导致同级节点无序。文章包含依赖、TreeNode类、TreeBuilder类、Org类和测试的详细内容,为确保线程安全,部分方法进行了优化。
摘要由CSDN通过智能技术生成

结构图

构建原理:
每新增一个newNode,则查看newNode是否是node节点(根节点)下某个child节点(node节点的List中的节点)的父节点,如果是,则移除这个节点child,并把这个节点child作为newNode的子节点。遍历完整个node节点的子节点集合(list)之后,把newNode节点插入到node中,设置父节点结束(由于newNode节点类似于一种吞并的方式,所以最后插入的到list的时候可能是无序的)。子节点采用递归的方式,依次对node下的每一个节点比较,满足newNode是某个节点的子节点,那么从node中移除newNode,并把newNode设置为这个节点的子节点,由于每个节点只有唯一一个父节点,一旦设置成功则退出,设置完毕。详细逻辑看源码。
由于构建的过程中涉及到节点的移动、增加、删除,所以是同级节点是无序的,后面源码有介绍排序方法。
在这里插入图片描述

1.依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

2.TreeNode

package com.example.datastucture.node.orgNode;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Setter
@Getter
@NoArgsConstructor
public class TreeNode<T> implements Serializable,Cloneable{
   
    private static final long serialVersionUID = -8685446899650372456L;
    private String id;
    private String pid;
    private String name;
    private T t;
    private ArrayList<TreeNode<T>> children = new ArrayList<>();

    public TreeNode(String id, String pid, String name, T t) {
   
        this.id = id;
        this.pid = pid;
        this.name = name;
        this.t = t;
    }

    /**
     * 这个clone方法只能拷贝当前对象和下一级children,children下面的TreeNode没法深拷贝,泛型也没法深拷贝。后续想办法
     * @return
     */
    @Override
    public TreeNode<T> clone(){
   
        TreeNode<T> treeNode = null;
        try {
   
            treeNode = (TreeNode<T>) super.clone();
            treeNode.children = (ArrayList<TreeNode<T>>) children.clone();
        } catch (CloneNotSupportedException e) {
   
            e.printStackTrace();
        }
        return treeNode;
    }
}


3.TreeBuilder

可直接调用的方法为了防止出现多线程并发的问题,所以设计成线程安全的实现。

package com.example.datastucture.node.orgNode;

import org.springframework.beans.BeanUtils;

import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * 线程安全的构建节点树
 */
public class TreeBuilder<T> {
   
    private TreeNode<T> node;
    private transient TreeNode<T> temp;

    public synchronized void add(@NotNull final TreeNode<T> newNode) {
   
        if (node == null) {
   
            node = new TreeNode<T>();
        }
        if (node.getChildren() == null) {
   
            node.setChildren(new ArrayList<>());
        }
        final TreeNode<T> currentNode = node;
        setNode(newNode, currentNode);
    }

    /**
     * 设置子节点
     * 这个依赖于父节点方法的设置,由父节点设置的原理,
     * 可以得出:当前节点(newNode)如果在node下的所有节点中存在一个父节点,那么这个父节点有且仅有一个。
     * 因此采用递归的方式设置子节
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值