天天看點

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

           

繼續閱讀