
com.moon.core.model.TreeElement Maven / Gradle / Ivy
package com.moon.core.model;
import com.moon.core.lang.ArrayUtil;
import com.moon.core.model.getter.*;
import java.util.*;
import java.util.function.Function;
/**
* 树形元素模板
*
* @author moonsky
*/
public class TreeElement implements IdGetter, NameGetter {
private String id;
private String name;
private List> children;
/**
* 携带的扩展数据
*/
private T data;
public TreeElement() { }
public TreeElement(String id, String name) {
this.name = name;
this.id = id;
}
public TreeElement(String id, String name, List> children) {
this(id, name);
this.children = children;
}
@SafeVarargs
public static List> fromKeyValueList(
Iterable data, Function... reGroupers
) { return fromKeyValueList(data, KeyGetter::getKey, reGroupers); }
@SafeVarargs
public static List> fromIdNameList(
Iterable data, Function... reGroupers
) { return fromIdNameList(data, IdGetter::getId, reGroupers); }
@SafeVarargs
public static List> fromKeyValueList(
Iterable data, Function grouper, Function... reGroupers
) { return fromList(data, grouper, KeyGetter::getKey, ValueGetter::getValue, reGroupers); }
@SafeVarargs
public static List> fromIdNameList(
Iterable data, Function grouper, Function... reGroupers
) { return fromList(data, grouper, IdGetter::getId, NameGetter::getName, reGroupers); }
/**
* 从数据列表中解析树形结构,注意参数{@code grouper}的返回值说明
*
* @param data 原数据
* @param grouper 分组函数;
* 返回值为父节点的 id;
* 若返回值为 null 代表没有父节点,可用来标记顶级节点
* @param idGetter 当前节点的 id,{@link #id}
* @param nameGetter 当前节点的 name,{@link #name}
* @param 数据类型
*
* @return 返回树形化后的每个顶级节点列表
*/
public static List> fromList(
Iterable data, Function grouper,
Function idGetter, Function nameGetter
) { return fromList(data, grouper, idGetter, nameGetter, (Function) null); }
/**
* 从数据列表中解析树形结构,注意参数{@code grouper}的返回值,null 值是有特殊意义的
*
* @param data 原数据
* @param grouper 分组函数;
* 返回值为父节点的 id;
* 若返回值为 null 代表没有父节点,可用来标记顶级节点
* @param idGetter 当前节点的 id,{@link #id}
* @param nameGetter 当前节点的 name,{@link #name}
* @param reGroupers 再分组函数(第一次【前一次】分组以及树形化之后,可能还剩余有数据,可以重新分组)
* @param 数据类型
*
* @return 返回树形化后的每个顶级节点列表
*/
@SafeVarargs
public static List> fromList(
Iterable data,
Function grouper,
Function idGetter,
Function nameGetter,
Function... reGroupers
) {
List> topParents = new ArrayList<>();
Map>> grouped = new HashMap<>();
for (T item : data) {
String key = grouper.apply(item);
if (key == null) {
TreeElement element = new TreeElement<>(idGetter.apply(item), nameGetter.apply(item));
element.setData(item);
topParents.add(element);
} else {
List> list = grouped.computeIfAbsent(key, k -> new ArrayList<>());
TreeElement element = new TreeElement<>(idGetter.apply(item), nameGetter.apply(item));
element.setData(item);
list.add(element);
}
}
doGroup(topParents, grouped);
// 再分组
if (!grouped.isEmpty() && ArrayUtil.isNotEmpty(reGroupers)) {
Map>> restGrouped = grouped;
for (Function groupFn : reGroupers) {
Map>> reGrouped = new HashMap<>();
for (Map.Entry>> listEntry : restGrouped.entrySet()) {
String reGroupKey = groupFn.apply(listEntry.getKey());
List> reGroupArr = reGrouped.get(reGroupKey);
if (reGroupArr == null) {
reGrouped.put(reGroupKey, listEntry.getValue());
} else {
reGroupArr.addAll(listEntry.getValue());
}
}
redoGroup(topParents, reGrouped);
if (reGrouped.isEmpty()) {
break;
} else {
restGrouped = reGrouped;
}
}
}
return topParents;
}
@Override
public String getId() { return id; }
public void setId(String id) { this.id = id; }
@Override
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public List> getChildren() { return children; }
public void setChildren(List> children) {
this.children = children;
}
public T getData() { return data; }
public void setData(T data) { this.data = data; }
/**
* 清空携带的扩展数据
*
* @return 当前对象
*/
public TreeElement clearExpandData() {
setData(null);
return this;
}
/**
* 清空当前以及子项所携带的扩展数据
*
* @return 当前对象
*/
public TreeElement clearAllExpandData() {
List> children = getChildren();
if (children != null) {
for (TreeElement child : children) {
if (child != null) {
child.clearAllExpandData();
}
}
}
return clearExpandData();
}
@Override
public boolean equals(Object o) {
if (this == o) { return true; }
if (o == null || getClass() != o.getClass()) { return false; }
TreeElement> that = (TreeElement>) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() { return Objects.hash(id); }
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("TreeElement{");
sb.append("id='").append(id).append('\'');
sb.append(", name='").append(name).append('\'');
sb.append(", children=").append(children);
sb.append(", data=").append(data);
sb.append('}');
return sb.toString();
}
/*
supports
*/
private static void redoGroup(List> parents, Map>> grouped) {
for (TreeElement parent : parents) {
String parentId = parent.getId();
List list = grouped.remove(parentId);
if (list != null) {
List> children = parent.getChildren();
if (children == null) {
parent.setChildren(list);
} else {
children.addAll(list);
}
redoGroup(list, grouped);
}
}
}
private static void doGroup(List> parents, Map>> grouped) {
for (TreeElement parent : parents) {
String parentId = parent.getId();
List list = grouped.remove(parentId);
if (list != null) {
parent.setChildren(list);
doGroup(list, grouped);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy