工作中碰到了樹形結構的一些需求
- 提供節點為null值的存儲
- 提供父節點的引用,且更新子節點時父節點所持有的子節點引用同步更新
- 提供查詢目前節點所處高度,父節點所處高度
- 即時挂載父節點,更改父節點時,同步更新父節點的父節點引用資訊,以及父節點的子節點引用資訊
- 類似雙向連結清單,對父項和子項資訊的同步更新進行null值考慮,并對多線程操作時考慮一些節點擁有的屬性的并發安全性問題
- 後續有需要會更新優化,如果有寫的欠缺的地方,請讀者在評論處指出
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;
}
}