
shz.core.model.TreeNode Maven / Gradle / Ivy
package shz.core.model;
import shz.core.NullHelp;
import shz.core.ToList;
import shz.core.ToMap;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
/**
* 树结构节点
*/
@SuppressWarnings("unchecked")
public class TreeNode> {
protected ID id;
protected List childes;
public final int count(Function func) {
Integer apply = func.apply((T) this);
int count = apply == null ? 0 : apply;
if (NullHelp.isEmpty(childes)) return count;
for (T t : childes) count += t.count(func);
return count;
}
public final int count() {
return count(t -> 1);
}
public final int leafCount() {
if (NullHelp.isEmpty(childes)) return 1;
int count = 0;
for (T t : childes) count += t.leafCount();
return count;
}
@SafeVarargs
public final List spread(Function firstMapper, BiFunction... mappers) {
R r = firstMapper.apply((T) this);
if (r == null) return Collections.emptyList();
if (NullHelp.isEmpty(mappers) || NullHelp.isEmpty(childes)) return Collections.singletonList(r);
List result = new ArrayList<>(leafCount());
for (T t : childes) t.spread(result, r, 0, mappers);
return result;
}
@SafeVarargs
final void spread(List result, R r, int level, BiFunction... mappers) {
if (level == mappers.length || NullHelp.isEmpty(childes)) {
result.add(r);
return;
}
for (T t : childes) t.spread(result, mappers[level].apply(r, t), level + 1, mappers);
}
public ID getId() {
return id;
}
public void setId(ID id) {
this.id = id;
}
public List getChildes() {
return childes;
}
public void setChildes(List childes) {
this.childes = childes;
}
@Override
public String toString() {
return "TreeNode{" +
"id=" + id +
", childes=" + childes +
'}';
}
/**
* 获取分组树
*
* @param list 需要分组的数据
* @param mapper 数据映射器
* @param lastMapper 最后分组数据映射器
* @param lastCollector 最后分组数据收集器
* @param classifiers 分组函数集
*/
@SafeVarargs
public static , R> List group(List list, BiFunction, T> mapper,
BiFunction lastMapper,
Collector lastCollector,
Function... classifiers) {
if (NullHelp.isEmpty(list)) return Collections.emptyList();
Collector> collector = Collectors.groupingBy(classifiers[classifiers.length - 1], lastCollector);
for (int i = classifiers.length - 2; i >= 0; --i) collector = Collectors.groupingBy(classifiers[i], collector);
return mergeGroup(list.stream().collect(collector), mapper, lastMapper);
}
private static , R> List mergeGroup(Map group, BiFunction, T> mapper, BiFunction lastMapper) {
return ToList.explicitCollect(group.keySet().stream().map(k -> {
Object nextGroup = group.get(k);
return nextGroup instanceof Map
? mapper.apply(k, mergeGroup((Map) nextGroup, mapper, lastMapper))
: lastMapper.apply(k, (R) nextGroup);
}), group.size());
}
/**
* 获取分组树
*
* @param list 需要分组的数据
* @param classifier 分类函数
* @param mapper 数据映射器
* @param nullMapper 空节点映射器
*/
public static > List group(List list, Function classifier, BiFunction mapper, Function nullMapper) {
if (NullHelp.isEmpty(list)) return Collections.emptyList();
Map> rootMap = new LinkedHashMap<>();
Map> levelChildesMap = new HashMap<>();
for (E e : list) {
if (e == null) continue;
String[] classifiers = classifier.apply(e);
int level = classifiers.length;
T t = mapper.apply(e, classifiers[level - 1]);
if (level == 1) rootMap.put(classifiers[0], new MapTreeNode<>(t));
else {
Map childesMap = levelChildesMap.computeIfAbsent(level, k -> new LinkedHashMap<>());
childesMap.put(t, classifiers);
}
}
int level = 1;
while (!levelChildesMap.isEmpty()) {
Map tMap = levelChildesMap.get(++level);
if (tMap == null) continue;
tMap.forEach((t, classifiers) -> {
MapTreeNode root = rootMap.get(classifiers[0]);
if (root == null) {
root = new MapTreeNode<>(nullMapper.apply(classifiers[0]));
root.childes = new LinkedHashMap<>();
rootMap.put(classifiers[0], root);
}
int limit = classifiers.length - 1;
MapTreeNode parent = root;
for (int i = 1; i < limit; ++i) {
MapTreeNode child = parent.childes.get(classifiers[i]);
if (child == null) {
child = new MapTreeNode<>(nullMapper.apply(classifiers[i]));
child.childes = new LinkedHashMap<>();
parent.childes.put(classifiers[i], child);
}
parent = child;
}
parent.childes.put(classifiers[limit], new MapTreeNode<>(t));
});
levelChildesMap.remove(level);
}
return ToList.explicitCollect(rootMap.values().stream().map(MapTreeNode::data), rootMap.size());
}
private static final class MapTreeNode> {
T data;
Map> childes;
MapTreeNode(T data) {
this.data = data;
}
T data() {
if (childes != null)
data.setChildes(ToList.explicitCollect(childes.values().stream().map(MapTreeNode::data), childes.size()));
return data;
}
}
/**
* 排序分组树
*/
public static > void sort(List nodes, Comparator comparator) {
if (NullHelp.isEmpty(nodes)) return;
nodes.sort(comparator);
nodes.forEach(node -> sort(node.getChildes(), comparator));
}
/**
* 合并分组树
*/
public static > List merge(List nodes, List otherNodes, BiFunction merger) {
if (NullHelp.isEmpty(nodes))
return otherNodes == null || otherNodes.isEmpty() ? Collections.emptyList() : otherNodes;
if (NullHelp.isEmpty(otherNodes)) return nodes;
Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy