java集合封装树型结构
创建一个抽象类(TreeDto.java)
import lombok.Data;
import java.util.List;
@Data
public abstract class TreeDto {
private List<TreeDto> children;
/**
* 获取当前类的id
* @return
*/
public abstract String getId();
/**
* 获取当前类的父节点id
* @return
*/
public abstract String getParentId();
/**
* 获取当前类的层级
* @return
*/
public abstract Integer getLevel();
/**
* 获取当前类的排序规则
* @return
*/
public abstract Comparable getSortOrder();
}
创建一个类对象,去继承TreeDto(Information.java)
import lombok.Data;
import java.util.List;
@Data
public abstract class Information extends TreeDto {
private String id;
private String parentId;
private String level;
private Integer sort;
/**
* 获取当前类的排序规则
* @return
*/
public Comparable getSortOrder() {
//如果需要多个字段的多种排序规则,则可以使用匿名内部类的形式实现
//return new Comparable<Integer>() {
// @Override
// public int compareTo(Integer o) {
// //此处为自定义排序规则
// return this > 0;
// }
//};
return this.getSort();
}
}
实现把List集合封装成树结构List
/**
* 把List集合封装成树结构
* @param list 此处是一个继承了TreeDto类的List集合
* @return
*/
public static List<TreeDto> list2SysTree(List<? extends TreeDto> list) {
//TODO 1.根据层进行分组
Map<Integer, List<TreeDto>> levelGroupMap = list.stream().collect(Collectors.groupingBy(t -> {
return t.getLevel();
}));
//TODO 2.每层根据parentId进行分组
Map<Integer, Map<String, List<TreeDto>>> levelParentGroupMap = new HashMap<>();
AtomicReference<Integer> maxLevel = new AtomicReference<>(0);
levelGroupMap.forEach((key, levelList) -> {
if (maxLevel.get() < key) {
maxLevel.set(key);
}
levelParentGroupMap.put(key, levelList.stream().collect(Collectors.groupingBy(t -> {
return t.getParentId();
})));
});
//TODO 3.倒着关联上去,获取第n层的map,在获取n-1层的list,遍历list,找到map中的children并关联
List<TreeDto> parentList = null;
Map<String, List<TreeDto>> childMap = null;
for (int level = maxLevel.get(); level > Constants.DEPARTMENTINFO_LEVEL; level--) {
parentList = levelGroupMap.get(level - 1);
childMap = levelParentGroupMap.get(level);
if (parentList == null) {
continue;//说明出现了断层,跳过,出现这种情况应该是中间一层的全删了,但是下层的没删,现在删除没有级联所以出现了脏数据
}
for (TreeDto parent : parentList) {
parent.setChildren(childMap.get(parent.getId()));
}
}
return levelGroupMap.get(Constants.DEPARTMENTINFO_LEVEL);
}
对封装好的树结构List进行排序
/**
* 对一个封装好的树结构进行排序
* @param tree 封装好的树结构
* @param orderMethod 排序方式
* @return
*/
public static List<TreeDto> list2SysTreeOrder(List<TreeDto> tree, SortOrderEnum orderMethod) {
if(CollectionUtil.isEmpty(tree)){
return new ArrayList<>();
}
tree.forEach(item->{
if(CollectionUtil.isNotEmpty(item.getChildren())){
list2SysTreeOrder(item.getChildren(), orderMethod);
item.setChildren(item.getChildren().stream().sorted((x,y)->{
int order = x.getSortOrder().compareTo(y.getSortOrder());
if(orderMethod.equals(SortOrderEnum.ASC)){
return order;
}else{
return -order;
}
}).collect(Collectors.toList()));
}
});
return tree;
}
测试用例
public static void main(String[] args) {
List<Information> list = new ArrayList<>();
List<TreeDto> tree = list2SysTree(list);
List<TreeDto> treeOrder = list2SysTreeOrder(tree, orderEnum);
System.out.println(treeOrder.toString());
}
测试完成就可以开心的使用啦
祝您生活愉快