java - listmap组装树形结构
package cn.seaboot.commons.core;
import cn.seaboot.commons.exception.BizException;
import cn.seaboot.commons.lang.Warning;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 数据组装树形结构(Map版本)
*
* @author Mr.css
* @version 2020-07-06 11:18
*/
public class TreeBuilder {
private List<Map<String, Object>> parent;
private List<Map<String, Object>> child;
private String idField = "id";
private String pidField = "pid";
private String childrenField = "children";
public List<Map<String, Object>> getParent() {
return parent;
}
public TreeBuilder setParent(List<Map<String, Object>> parent) {
this.parent = parent;
return this;
}
public List<Map<String, Object>> getChild() {
return child;
}
public TreeBuilder setChild(List<Map<String, Object>> child) {
this.child = child;
return this;
}
public TreeBuilder setIdField(String idField) {
this.idField = idField;
return this;
}
public TreeBuilder setPidField(String pidField) {
this.pidField = pidField;
return this;
}
public TreeBuilder setChildrenField(String childrenField) {
this.childrenField = childrenField;
return this;
}
/**
* 数据分组
*
* @return TreeBuilder
*/
@SuppressWarnings(Warning.UNCHECKED)
public TreeBuilder groupBy() {
if (child == null) {
child = parent;
}
for (Map<String, Object> p : parent) {
for (Map<String, Object> c : child) {
if (p.get(this.idField).equals(c.get(this.pidField))) {
List<Map<String, Object>> list = (List<Map<String, Object>>) p.get(this.childrenField);
if (list == null) {
list = new ArrayList<>();
p.put(this.childrenField, list);
}
list.add(c);
}
}
}
return this;
}
/**
* 如果已知要取的节点,直接按照节点pId进行获取
*
* @return tree
*/
public List<Map<String, Object>> getByPid(@Nullable Object pidValue) {
List<Map<String, Object>> res = new ArrayList<>();
if (pidValue == null) {
for (Map<String, Object> p : parent) {
if (p.get(pidField) == null) {
res.add(p);
}
}
} else {
for (Map<String, Object> p : parent) {
if (p.get(pidField).equals(pidValue)) {
res.add(p);
}
}
}
return res;
}
/**
* 从组装的结果中取出Pid最小的数据
*
* @return tree
*/
@SuppressWarnings({Warning.UNCHECKED, Warning.RAW_TYPES})
public List<Map<String, Object>> getByMinPid() {
Comparable min = (Comparable) parent.get(0).get(pidField);
Comparable obj;
for (Map<String, Object> p : parent) {
obj = (Comparable) p.get(pidField);
if (obj.compareTo(min) < 0) {
min = obj;
}
}
return this.getByPid(min);
}
/**
* 从组装的结果中取出Pid最大的数据
*
* @return tree
* @throws ClassCastException List元素未继承自Comparable接口
*/
@SuppressWarnings({Warning.UNCHECKED, Warning.RAW_TYPES})
public List<Map<String, Object>> getByMaxPid() {
Comparable max = (Comparable) parent.get(0).get(pidField);
Comparable obj;
for (Map<String, Object> p : parent) {
obj = (Comparable) p.get(pidField);
if (obj.compareTo(max) > 0) {
max = obj;
}
}
return this.getByPid(max);
}
/**
* 随机取出一个元素,反复遍历树,直到取出最顶级的父节点
*
* @return tree
* @throws ClassCastException List元素未继承自Comparable接口
*/
@SuppressWarnings({Warning.UNCHECKED, Warning.RAW_TYPES})
public List<Map<String, Object>> getRoot() {
// 存在 pid 为 null 的数据
for (Map<String, Object> p : parent) {
if (p.get(pidField) == null) {
return this.getByPid(null);
}
}
Comparable max = (Comparable) parent.get(0).get(pidField);
// 已经查找过的节点
List<Comparable> list = new ArrayList<>();
while (true) {
// 查找更大的父节点
Comparable pid = null;
for (Map<String, Object> p : parent) {
if (max.compareTo(p.get(idField)) == 0) {
pid = (Comparable) p.get(pidField);
break;
}
}
if (pid == null) {
// 找不到更大的节点,与 for 循环中的空值判断含义不同
return this.getByPid(max);
} else {
max = pid;
// 判断是否发生循环依赖,不然会发生无线循环
if (list.contains(max)) {
throw new BizException("Circular dependencies");
} else {
list.add(max);
}
}
}
}
}
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!