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

com.power4j.coca.kit.common.collection.tree.TreeNodeUtil 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 lombok.Builder; import lombok.Getter; import lombok.experimental.UtilityClass; import org.apache.commons.lang3.ObjectUtils; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; /** * @author CJ ([email protected]) * @date 2022/5/9 * @since 2022.0.3 */ @UtilityClass public class TreeNodeUtil { /** * 迭代树节点 * @param roots 根节点 * @param consumer 节点消费函数 * @param ID 类型 * @param Node 子类 */ public > void treeWalk(Collection roots, Consumer consumer) { for (final N node : roots) { consumer.accept(node); List children = node.getChildren(); if (ObjectUtils.isNotEmpty(children)) { treeWalk(children, consumer); } } } /** * 根据属性排序 * @param list 根节点 * @param keyExtractor 属性取值函数 * @param ID 类型 * @param Node 子类 */ public static , U extends Comparable> void sortNodes(final List list, final Function keyExtractor) { list.sort(Comparator.comparing(keyExtractor)); for (N node : list) { final List children = node.getChildren(); if (ObjectUtils.isNotEmpty(children)) { sortNodes(children, keyExtractor); } } } /** * 树节点转list * @param roots 根节点 * @param ID 类型 * @param Node 子类 * @return 返回节点MAP */ public > List flatten(List roots) { List list = new ArrayList<>(roots.size()); treeWalk(roots, list::add); return list; } /** * 填充子级 * @param source 数据源 * @param roots 根节点 * @param ID 类型 * @param Node 子类 */ public > void fetch(Map source, Map roots) { if (roots.isEmpty()) { return; } for (N node : source.values()) { if (null == node) { continue; } final ID id = Objects.requireNonNull(node.getId()); if (roots.containsKey(id)) { continue; } final ID parentId = node.getParentId(); final N parentNode = Optional.ofNullable(roots.get(parentId)).orElseGet(() -> source.get(parentId)); if (null != parentNode) { parentNode.appendChild(node); } } } /** * 转换为其他类型,无接口依赖 * @param src 数据源 * @param op 转换所需各种函数 * @param dist 用于保存结果 * @param ID 类型 * @param 原类型 * @param 目标类型 */ public , U> void convert(Collection src, ConvertOp op, Collection dist) { for (N node : src) { final U target = op.objectConvert.apply(node); dist.add(target); final List children = node.getChildren(); if (ObjectUtils.isNotEmpty(children)) { final List list = new ArrayList<>(2); convert(children, op, list); op.childSetter.accept(target, list); } } } /** * 转换为其他类型,无接口依赖 * @param src 数据源 * @param op 转换所需各种函数 * @param ID 类型 * @param 原类型 * @param 目标类型 * @return 返回转换后的列表 */ public , U> List convertToList(Collection src, ConvertOp op) { List list = new ArrayList<>(2); convert(src, op, list); return list; } @Getter @Builder public static class ConvertOp { /** * 取ID的方法 */ private final Function objectConvert; /** * 添加子元素的方法 */ private final BiConsumer> childSetter; } }