天天看点

Java自定义树形结构(仅限工作快速开发使用,非高深代码)

工作中碰到了树形结构的一些需求

  1. 提供节点为null值的存储
  2. 提供父节点的引用,且更新子节点时父节点所持有的子节点引用同步更新
  3. 提供查询当前节点所处高度,父节点所处高度
  4. 即时挂载父节点,更改父节点时,同步更新父节点的父节点引用信息,以及父节点的子节点引用信息
  5. 类似双向链表,对父项和子项信息的同步更新进行null值考虑,并对多线程操作时考虑一些节点拥有的属性的并发安全性问题
  6. 后续有需要会更新优化,如果有写的欠缺的地方,请读者在评论处指出
package com.xxxx;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.util.CollectionUtils;

public class CommonNode<T> {
	private T data;
	private CommonNode<T> parentNode;
	private AtomicInteger currentNodeHeight;
	private AtomicInteger parentNodeHeight;
	private List<CommonNode<T>> childCommonNodes;

	private <T> CommonNode() {
	}

	/**
	 * 无父节点构造方法
	 * 
	 * @param data
	 */
	public CommonNode(final T data) {
		if (data != null) {
			this.setData(data);
		}
		this.currentNodeHeight = new AtomicInteger(0);
		this.parentNodeHeight = new AtomicInteger(-1);
	}

	/**
	 * 带父节点构造方法
	 * 
	 * @param data
	 * @param parentNode
	 */
	public CommonNode(final T data, final CommonNode<T> parentNode) {
		if (data != null) {
			this.setData(data);
		}
		if (parentNode != null) {
			this.setParentNode(parentNode);
		} else {
			this.currentNodeHeight = new AtomicInteger(0);
			this.parentNodeHeight = new AtomicInteger(-1);
		}
	}

	public void setData(final T data) {
		this.data = data;
	}

	public T getData() {
		return data;
	}

	public void setParentNode(final CommonNode<T> parentNode) {
		// 之前连接的如果有父节点,需要把父节点中持有的引用删掉
		CommonNode<T> beforeAddParentNode = this.getParentNode();
		if (beforeAddParentNode != null) {
			List<CommonNode<T>> beforeAddChildCommonNodes = beforeAddParentNode.getChildCommonNodes();
			if (!CollectionUtils.isEmpty(beforeAddChildCommonNodes)) {
				beforeAddChildCommonNodes.remove(this);
			}
		} else {
			List<CommonNode<T>> curCommonNodes = parentNode.getChildCommonNodes();
			if (curCommonNodes == null) {
				curCommonNodes = new CopyOnWriteArrayList<>();
				parentNode.setChildCommonNodes(curCommonNodes);
			}
			curCommonNodes.add(this);

		}

		this.parentNode = parentNode;
		this.parentNodeHeight = parentNode.getCurrentNodeHeight();
		this.currentNodeHeight = new AtomicInteger(parentNode.getCurrentNodeHeight().get()+1);
	}

	public AtomicInteger getCurrentNodeHeight() {
		return currentNodeHeight;
	}

	private void setCurrentNodeHeight(final AtomicInteger newCurrentNodeHeight) {
		currentNodeHeight = newCurrentNodeHeight;
	}

	public CommonNode<T> getParentNode() {
		return parentNode;
	}

	public AtomicInteger getParentNodeHeight() {
		return parentNodeHeight;
	}

	private void setParentNodeHeight(final AtomicInteger newParentNodeHeight) {
		parentNodeHeight = newParentNodeHeight;
	}

	public List<CommonNode<T>> getChildCommonNodes() {
		return childCommonNodes;
	}

	public void setChildCommonNodes(final List<CommonNode<T>> newChildCommonNodes) {
		childCommonNodes = newChildCommonNodes;
	}
}

           

继续阅读