表结构
RecursionBean
@Getter
@Setter
@ToString
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class RecursionBean<T> extends BaseVO {
private T id;
private T pid;
private List<? extends RecursionBean<T>> children;
}
封装从服务器端返回的树形数据:RecursionItem
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class RecursionItem<T> extends RecursionBean<T> {
private String name;
public RecursionItem(T id, String name) {
super.setId(id);
this.name = name;
}
public RecursionItem(T id, String name, List<? extends RecursionBean<T>> children) {
super.setId(id);
this.name = name;
super.setChildren(children);
}
}
工具类
public class RecursionBeanUtil {
private static <E, T extends RecursionBean<E>> List<T> getChildren(T root, List<T> list) {
final List<T> res = new ArrayList<>();
for (T item : list) {
if (Objects.equals(item.getPid(), root.getId())) {
item.setChildren(getChildren(item, list));
res.add(item);
}
}
return res;
}
public static <E, T extends RecursionBean<E>> List<T> getRecursionList(List<T> list) {
if (CollectionUtil.isEmpty(list)) {
return list;
}
final List<E> allList = list.stream()
.map(T::getId)
.toList();
final List<E> topList = list.stream()
.filter(item -> item.getPid() == null)
.map(T::getId)
.toList();
final List<E> parentList = list.stream()
.map(T::getPid)
.filter(itemPid -> !topList.contains(itemPid))
.distinct()
.toList();
final List<E> leafList = allList.stream()
.filter(id -> !topList.contains(id))
.filter(id -> !parentList.contains(id))
.toList();
final List<T> res = new ArrayList<>();
boolean topFlag = true;
for (T item : list) {
if (item.getPid() == null) {
topFlag = false;
item.setChildren(getChildren(item, list));
res.add(item);
}
}
if (!topFlag) {
return res;
}
boolean parentFlag = true;
for (T item : list) {
if (parentList.contains(item.getPid()) && !leafList.contains(item.getId())) {
item.setChildren(getChildren(item, list));
parentFlag = false;
res.add(item);
}
}
if (!parentFlag) {
return res;
}
for (T item : list) {
if (leafList.contains(item.getId())) {
item.setChildren(getChildren(item, list));
res.add(item);
}
}
return res;
}
}