mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-03 20:27:58 +08:00
add Node
This commit is contained in:
parent
4663e0d175
commit
d330c489b3
@ -13,7 +13,7 @@
|
||||
* 【core 】 XmlUtil增加xmlToBean和beanToXml方法
|
||||
* 【db 】 设置全局忽略大小写DbUtil.setCaseInsensitiveGlobal(true)(issue#784@Github)
|
||||
* 【core 】 增加CallerUtil.getCallerMethodName方法
|
||||
* 【core 】 Tree增加getParent方法,可以获取父节点
|
||||
* 【core 】 Tree增加getParent方法,可以获取父节点,抽象Node接口
|
||||
|
||||
### Bug修复
|
||||
* 【core 】 修复TypeUtil无法获取泛型接口的泛型参数问题(issue#I1BRFI@Gitee)
|
||||
|
79
hutool-core/src/main/java/cn/hutool/core/lang/tree/Node.java
Normal file
79
hutool-core/src/main/java/cn/hutool/core/lang/tree/Node.java
Normal file
@ -0,0 +1,79 @@
|
||||
package cn.hutool.core.lang.tree;
|
||||
|
||||
/**
|
||||
* 节点接口,提供节点相关的的方法定义
|
||||
*
|
||||
* @param <T> ID类型
|
||||
* @author looly
|
||||
* @since 5.2.4
|
||||
*/
|
||||
public interface Node<T> extends Comparable<Node<T>>{
|
||||
/**
|
||||
* 获取ID
|
||||
*
|
||||
* @return ID
|
||||
*/
|
||||
T getId();
|
||||
|
||||
/**
|
||||
* 设置ID
|
||||
*
|
||||
* @param id ID
|
||||
*/
|
||||
Node<T> setId(T id);
|
||||
|
||||
/**
|
||||
* 获取父节点ID
|
||||
*
|
||||
* @return 父节点ID
|
||||
*/
|
||||
T getParentId();
|
||||
|
||||
/**
|
||||
* 设置父节点ID
|
||||
*
|
||||
* @param parentId 父节点ID
|
||||
* @return 父节点ID
|
||||
*/
|
||||
Node<T> setParentId(T parentId);
|
||||
|
||||
/**
|
||||
* 获取节点标签名称
|
||||
*
|
||||
* @return 节点标签名称
|
||||
*/
|
||||
CharSequence getName();
|
||||
|
||||
/**
|
||||
* 设置节点标签名称
|
||||
*
|
||||
* @param name 节点标签名称
|
||||
* @return this
|
||||
*/
|
||||
Node<T> setName(CharSequence name);
|
||||
|
||||
/**
|
||||
* 获取权重
|
||||
*
|
||||
* @return 权重
|
||||
*/
|
||||
Comparable<?> getWeight();
|
||||
|
||||
/**
|
||||
* 设置权重
|
||||
*
|
||||
* @param weight 权重
|
||||
* @return this
|
||||
*/
|
||||
Node<T> setWeight(Comparable<?> weight);
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems"})
|
||||
default int compareTo(Node node) {
|
||||
final Comparable weight = this.getWeight();
|
||||
if (null != weight) {
|
||||
final Comparable weightOther = node.getWeight();
|
||||
return weight.compareTo(weightOther);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ package cn.hutool.core.lang.tree;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
@ -14,7 +13,7 @@ import java.util.List;
|
||||
* @author liangbaikai
|
||||
* @since 5.2.1
|
||||
*/
|
||||
public class Tree<T> extends LinkedHashMap<String, Object> implements Comparable<Tree<T>> {
|
||||
public class Tree<T> extends LinkedHashMap<String, Object> implements Node<T> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private TreeNodeConfig treeNodeConfig;
|
||||
@ -54,21 +53,23 @@ public class Tree<T> extends LinkedHashMap<String, Object> implements Comparable
|
||||
* @since 5.2.4
|
||||
*/
|
||||
public Tree<T> getNode(T id) {
|
||||
if (ObjectUtil.equal(id, getId())) {
|
||||
return this;
|
||||
}
|
||||
return TreeUtil.getNode(this, id);
|
||||
}
|
||||
|
||||
// 查找子节点
|
||||
Tree<T> node;
|
||||
for (Tree<T> child : getChildren()) {
|
||||
node = child.getNode(id);
|
||||
if (null != node) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
// 未找到节点
|
||||
return null;
|
||||
/**
|
||||
* 获取所有父节点名称列表
|
||||
*
|
||||
* <p>
|
||||
* 比如有个人在研发1部,他上面有研发部,接着上面有技术中心<br>
|
||||
* 返回结果就是:[研发一部, 研发中心, 技术中心]
|
||||
*
|
||||
* @param id 节点ID
|
||||
* @param includeCurrentNode 是否包含当前节点的名称
|
||||
* @return 所有父节点名称列表
|
||||
* @since 5.2.4
|
||||
*/
|
||||
public List<CharSequence> getParentsName(T id, boolean includeCurrentNode) {
|
||||
return TreeUtil.getParentsName(getNode(id), includeCurrentNode);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,17 +84,7 @@ public class Tree<T> extends LinkedHashMap<String, Object> implements Comparable
|
||||
* @since 5.2.4
|
||||
*/
|
||||
public List<CharSequence> getParentsName(boolean includeCurrentNode) {
|
||||
final List<CharSequence> result = new ArrayList<>();
|
||||
if (includeCurrentNode) {
|
||||
result.add(this.getName());
|
||||
}
|
||||
|
||||
Tree<T> parent = getParent();
|
||||
while (null != parent) {
|
||||
result.add(parent.getName());
|
||||
parent = parent.getParent();
|
||||
}
|
||||
return result;
|
||||
return TreeUtil.getParentsName(this, includeCurrentNode);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,55 +101,47 @@ public class Tree<T> extends LinkedHashMap<String, Object> implements Comparable
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点ID
|
||||
*
|
||||
* @return 节点ID
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T getId() {
|
||||
return (T) this.get(treeNodeConfig.getIdKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置节点ID
|
||||
*
|
||||
* @param id 节点ID
|
||||
* @return this
|
||||
*/
|
||||
@Override
|
||||
public Tree<T> setId(T id) {
|
||||
this.put(treeNodeConfig.getIdKey(), id);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取父节点ID
|
||||
*
|
||||
* @return 父节点ID
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T getParentId() {
|
||||
return (T) this.get(treeNodeConfig.getParentIdKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tree<T> setParentId(T parentId) {
|
||||
this.put(treeNodeConfig.getParentIdKey(), parentId);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getName() {
|
||||
return (CharSequence) this.get(treeNodeConfig.getNameKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tree<T> setName(CharSequence name) {
|
||||
this.put(treeNodeConfig.getNameKey(), name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparable<?> getWeight() {
|
||||
return (Comparable<?>) this.get(treeNodeConfig.getWeightKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tree<T> setWeight(Comparable<?> weight) {
|
||||
this.put(treeNodeConfig.getWeightKey(), weight);
|
||||
return this;
|
||||
@ -183,15 +166,4 @@ public class Tree<T> extends LinkedHashMap<String, Object> implements Comparable
|
||||
Assert.notEmpty(key, "Key must be not empty !");
|
||||
this.put(key, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked", "NullableProblems"})
|
||||
@Override
|
||||
public int compareTo(Tree<T> tree) {
|
||||
final Comparable weight = this.getWeight();
|
||||
if (null != weight) {
|
||||
final Comparable weightOther = tree.getWeight();
|
||||
return weight.compareTo(weightOther);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -6,9 +6,10 @@ package cn.hutool.core.lang.tree;
|
||||
* 在你的项目里它可以是部门实体、地区实体等任意类树节点实体
|
||||
* 类树节点实体: 包含key,父Key.不限于这些属性的可以构造成一颗树的实体对象
|
||||
*
|
||||
* @param <T> ID类型
|
||||
* @author liangbaikai
|
||||
*/
|
||||
public class TreeNode<T> implements Comparable<Tree<T>> {
|
||||
public class TreeNode<T> implements Node<T> {
|
||||
|
||||
/**
|
||||
* ID
|
||||
@ -55,92 +56,47 @@ public class TreeNode<T> implements Comparable<Tree<T>> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ID
|
||||
*
|
||||
* @return ID
|
||||
*/
|
||||
@Override
|
||||
public T getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置ID
|
||||
*
|
||||
* @param id ID
|
||||
*/
|
||||
public void setId(T id) {
|
||||
@Override
|
||||
public TreeNode<T> setId(T id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取父节点ID
|
||||
*
|
||||
* @return 父节点ID
|
||||
*/
|
||||
@Override
|
||||
public T getParentId() {
|
||||
return this.parentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置父节点ID
|
||||
*
|
||||
* @param parentId 父节点ID
|
||||
* @return 父节点ID
|
||||
*/
|
||||
@Override
|
||||
public TreeNode<T> setParentId(T parentId) {
|
||||
this.parentId = parentId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点标签名称
|
||||
*
|
||||
* @return 节点标签名称
|
||||
*/
|
||||
@Override
|
||||
public CharSequence getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置节点标签名称
|
||||
*
|
||||
* @param name 节点标签名称
|
||||
* @return this
|
||||
*/
|
||||
@Override
|
||||
public TreeNode<T> setName(CharSequence name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取权重
|
||||
*
|
||||
* @return 权重
|
||||
*/
|
||||
@Override
|
||||
public Comparable<?> getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置权重
|
||||
*
|
||||
* @param weight 权重
|
||||
* @return this
|
||||
*/
|
||||
@Override
|
||||
public TreeNode<T> setWeight(Comparable<?> weight) {
|
||||
this.weight = weight;
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems"})
|
||||
@Override
|
||||
public int compareTo(Tree tree) {
|
||||
final Comparable weight = this.getWeight();
|
||||
if (null != weight) {
|
||||
final Comparable weightOther = tree.getWeight();
|
||||
return weight.compareTo(weightOther);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package cn.hutool.core.lang.tree;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.tree.parser.DefaultNodeParser;
|
||||
import cn.hutool.core.lang.tree.parser.NodeParser;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -117,4 +119,61 @@ public class TreeUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ID对应的节点,如果有多个ID相同的节点,只返回第一个。<br>
|
||||
* 此方法只查找此节点及子节点,采用广度优先遍历。
|
||||
*
|
||||
* @param id ID
|
||||
* @return 节点
|
||||
* @since 5.2.4
|
||||
*/
|
||||
public static <T> Tree<T> getNode(Tree<T> node, T id) {
|
||||
if (ObjectUtil.equal(id, node.getId())) {
|
||||
return node;
|
||||
}
|
||||
|
||||
// 查找子节点
|
||||
Tree<T> childNode;
|
||||
for (Tree<T> child : node.getChildren()) {
|
||||
childNode = child.getNode(id);
|
||||
if (null != childNode) {
|
||||
return childNode;
|
||||
}
|
||||
}
|
||||
|
||||
// 未找到节点
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有父节点名称列表
|
||||
*
|
||||
* <p>
|
||||
* 比如有个人在研发1部,他上面有研发部,接着上面有技术中心<br>
|
||||
* 返回结果就是:[研发一部, 研发中心, 技术中心]
|
||||
*
|
||||
* @param <T> 节点ID类型
|
||||
* @param node 节点
|
||||
* @param includeCurrentNode 是否包含当前节点的名称
|
||||
* @return 所有父节点名称列表,node为null返回空List
|
||||
* @since 5.2.4
|
||||
*/
|
||||
public static <T> List<CharSequence> getParentsName(Tree<T> node, boolean includeCurrentNode) {
|
||||
final List<CharSequence> result = new ArrayList<>();
|
||||
if(null == node){
|
||||
return result;
|
||||
}
|
||||
|
||||
if (includeCurrentNode) {
|
||||
result.add(node.getName());
|
||||
}
|
||||
|
||||
Tree<T> parent = node.getParent();
|
||||
while (null != parent) {
|
||||
result.add(parent.getName());
|
||||
parent = parent.getParent();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user