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

com.power4j.coca.kit.common.collection.tree.TreeMaker Maven / Gradle / Ivy

/*
 * Copyright 2021 ChenJun ([email protected] & https://github.com/John-Chan)
 *
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 

* http://www.gnu.org/licenses/lgpl.html *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.power4j.coca.kit.common.collection.tree; import com.power4j.coca.kit.common.collection.tree.domain.Node; import com.power4j.coca.kit.common.collection.tree.domain.NodeIdx; import com.power4j.coca.kit.common.collection.tree.domain.TreeNode; import org.apache.commons.lang3.ObjectUtils; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; /** * @author CJ ([email protected]) * @date 2022/5/7 * @since 2022.0.3 * @param ID 类型 * @param Node 子类 */ public class TreeMaker> { private final Map data; TreeMaker(Map data) { this.data = data; } /** * 构造方法 * @param data 业务数据 * @param ID 类型 * @param Node 子类 * @return 返回实例 */ public static > TreeMaker use(Collection data) { Map sourceData = data.stream() .collect(Collectors.toMap(Node::getId, Function.identity(), (x, y) -> y, LinkedHashMap::new)); return new TreeMaker<>(sourceData); } /** * 构造方法 * @param nodes 树形节点索引 * @param ID 类型 * @return 返回实例 */ public static TreeMaker> useIdx(Collection> nodes) { Function> treeMapper = id -> TreeNode.of(id, null); Map parentMap = nodes.stream() .filter(o -> (1 == o.getDistance())) .collect(Collectors.toMap(NodeIdx::getDescendant, NodeIdx::getAncestor)); Map> data = nodes.stream() .filter(o -> (0 == o.getDistance())) .map(NodeIdx::getAncestor) .map(treeMapper) .collect(Collectors.toMap(TreeNode::getId, Function.identity(), (x, y) -> y, LinkedHashMap::new)); data.values().forEach(o -> o.setParentId(parentMap.get(o.getId()))); return new TreeMaker<>(data); } /** * 构建树形结构 * @param id 根点ID,必须存在于数据源中,并且不是顶层节点 * @return 返回树形结构,如果数据源不包含根节点数据则返回empty */ public Optional build(ID id) { List roots = build(o -> Objects.equals(o.getId(), id)); return roots.stream().findFirst(); } /** * 构建树形结构,自动推测根节点 * @return 返回根节点列表 */ public List build() { return makeTree(TreeMaker::findTopNodes); } /** * 构建树形结构 * @param rootPred 根节点断言 * @return 返回根节点列表,如果数据源不包含根节点数据则返回empty */ public List build(Predicate rootPred) { // @formatter:off Function,Map> rootSelect = map -> map.entrySet() .stream() .filter(et -> rootPred.test(et.getValue())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new)); // @formatter:on return makeTree(rootSelect); } /** * 构建树形结构 支持多个根节点 * @param rootSelect 根节选择器 * @return 返回根节点列表,如果数据源不包含根节点数据则返回empty */ protected List makeTree(Function, Map> rootSelect) { if (ObjectUtils.isEmpty(data)) { return Collections.emptyList(); } // 根节点 final Map roots = rootSelect.apply(data); if (ObjectUtils.isEmpty(roots)) { return Collections.emptyList(); } TreeNodeUtil.fetch(data, roots); return new ArrayList<>(roots.values()); } // ~ Utils // =================================================================================================== protected static > Map findTopNodes(Map input) { return TreeUtil.findAncestors(input, N::getId, N::getParentId); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy