All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jchanghong.core.lang.tree.TreeUtil Maven / Gradle / Ivy

The newest version!
package com.jchanghong.core.lang.tree;

import com.jchanghong.core.collection.CollUtil;
import com.jchanghong.core.lang.tree.parser.DefaultNodeParser;
import com.jchanghong.core.lang.tree.parser.NodeParser;
import com.jchanghong.core.util.ObjectUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 树工具类
 *
 * @author liangbaikai
 */
public class TreeUtil {

	/**
	 * 树构建
	 *
	 * @param list 源数据集合
	 * @return List
	 */
	public static List> build(List> list) {
		return build(list, 0);
	}

	/**
	 * 树构建
	 *
	 * @param       ID类型
	 * @param list     源数据集合
	 * @param parentId 最顶层父id值 一般为 0 之类
	 * @return List
	 */
	public static  List> build(List> list, E parentId) {
		return build(list, parentId, TreeNodeConfig.DEFAULT_CONFIG, new DefaultNodeParser<>());
	}

	/**
	 * 树构建
	 *
	 * @param         转换的实体 为数据源里的对象类型
	 * @param         ID类型
	 * @param list       源数据集合
	 * @param parentId   最顶层父id值 一般为 0 之类
	 * @param nodeParser 转换器
	 * @return List
	 */
	public static  List> build(List list, E parentId, NodeParser nodeParser) {
		return build(list, parentId, TreeNodeConfig.DEFAULT_CONFIG, nodeParser);
	}

	/**
	 * 树构建
	 *
	 * @param             转换的实体 为数据源里的对象类型
	 * @param             ID类型
	 * @param list           源数据集合
	 * @param parentId       最顶层父id值 一般为 0 之类
	 * @param treeNodeConfig 配置
	 * @param nodeParser     转换器
	 * @return List
	 */
	public static  List> build(List list, E parentId, TreeNodeConfig treeNodeConfig, NodeParser nodeParser) {
		final List> treeList = CollUtil.newArrayList();
		Tree tree;
		for (T obj : list) {
			tree = new Tree<>(treeNodeConfig);
			nodeParser.parse(obj, tree);
			treeList.add(tree);
		}

		List> finalTreeList = CollUtil.newArrayList();
		for (Tree node : treeList) {
			if (parentId.equals(node.getParentId())) {
				finalTreeList.add(node);
				innerBuild(treeList, node, 0, treeNodeConfig.getDeep());
			}
		}
		// 内存每层已经排过了 这是最外层排序
		finalTreeList = finalTreeList.stream().sorted().collect(Collectors.toList());
		return finalTreeList;
	}

	/**
	 * 递归处理
	 *
	 * @param treeNodes  数据集合
	 * @param parentNode 当前节点
	 * @param deep       已递归深度
	 * @param maxDeep    最大递归深度 可能为null即不限制
	 */
	private static  void innerBuild(List> treeNodes, Tree parentNode, int deep, Integer maxDeep) {

		if (CollUtil.isEmpty(treeNodes)) {
			return;
		}
		//maxDeep 可能为空
		if (maxDeep != null && deep >= maxDeep) {
			return;
		}

		// 每层排序 TreeNodeMap 实现了Comparable接口
		treeNodes = treeNodes.stream().sorted().collect(Collectors.toList());
		for (Tree childNode : treeNodes) {
			if (parentNode.getId().equals(childNode.getParentId())) {
				List> children = parentNode.getChildren();
				if (children == null) {
					children = CollUtil.newArrayList();
					parentNode.setChildren(children);
				}
				children.add(childNode);
//				childNode.setParentId(parentNode.getId());
				childNode.setParent(parentNode);
				innerBuild(treeNodes, childNode, deep + 1, maxDeep);
			}
		}
	}

	/**
	 * 获取ID对应的节点,如果有多个ID相同的节点,只返回第一个。
* 此方法只查找此节点及子节点,采用广度优先遍历。 * * @param ID类型 * @param node 节点 * @param id ID * @return 节点 * @since 5.2.4 */ public static Tree getNode(Tree node, T id) { if (ObjectUtil.equal(id, node.getId())) { return node; } final List> children = node.getChildren(); if(null == children) { return null; } // 查找子节点 Tree childNode; for (Tree child : children) { childNode = child.getNode(id); if (null != childNode) { return childNode; } } // 未找到节点 return null; } /** * 获取所有父节点名称列表 * *

* 比如有个人在研发1部,他上面有研发部,接着上面有技术中心
* 返回结果就是:[研发一部, 研发中心, 技术中心] * * @param 节点ID类型 * @param node 节点 * @param includeCurrentNode 是否包含当前节点的名称 * @return 所有父节点名称列表,node为null返回空List * @since 5.2.4 */ public static List getParentsName(Tree node, boolean includeCurrentNode) { final List result = new ArrayList<>(); if(null == node){ return result; } if (includeCurrentNode) { result.add(node.getName()); } Tree parent = node.getParent(); while (null != parent) { result.add(parent.getName()); parent = parent.getParent(); } return result; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy