com.power4j.tile.collection.tree.TreeMaker Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* 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.tile.collection.tree;
import com.power4j.tile.collection.tree.domain.Node;
import com.power4j.tile.collection.tree.domain.NodeIdx;
import com.power4j.tile.collection.tree.domain.TreeNode;
import org.springframework.util.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])
* @since 1.0
* @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 extends NodeIdx> 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