Java 高效构建树形结构
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
/**
* 构造数据树 O(N)
*
* @param list 原集合
* @param mKey 父级被子集关联的字段,比如id
* @param treeConnectKey 子集关联父级的字段,比如parentId
* @param treeSortKey 同级菜单的排序字段,比如sort
* @param consumer 添加子集的函数,如(list)
* @param <M>
* @return
*/
public static <M> List<M> buildTree(List<M> list, Function<M, ?> mKey, Function<M, ?> treeConnectKey,
Function<M, ? extends Comparable> treeSortKey, Consumers<M, M> consumer) {
if (CollUtil.isEmpty(list)) {
return Collections.emptyList();
}
Assert.notNull(mKey, "父级被子级关联的字段不能为空");
Assert.notNull(treeConnectKey, "子级关联父级的字段不能为空");
Assert.notNull(consumer, "消费函数不能为空");
//线程安全类集合
List<M> tree = Collections.synchronizedList(new ArrayList<>());
//按上级id分组
final Map<?, List<M>> collect = list.parallelStream().collect(Collectors.groupingBy(treeConnectKey));
list.parallelStream().filter(m -> {
final boolean b = (Long) treeConnectKey.apply(m) != 0L;
if (!b) {
tree.add(m);
}
return b;
}).forEach(
//通过对象地址引用实现父子级关联,即使父级先添加了子级,子级在添加孙子级,父子孙三级也全部都会关联
m -> {
if (treeSortKey != null) {
consumer.accept(m, CollUtil.sort(collect.get(mKey.apply(m)), java.util.Comparator.comparing(treeSortKey)));
} else {
consumer.accept(m, collect.get(mKey.apply(m)));
}
}
);
if (treeSortKey != null) {
//排序
tree.sort(java.util.Comparator.comparing(treeSortKey));
return tree.parallelStream().peek(b -> consumer.accept(b, CollUtil.sort(collect.get(mKey.apply(b)), java.util.Comparator.comparing(treeSortKey)))).collect(Collectors.toList());
} else {
return tree.parallelStream().peek(b -> consumer.accept(b, collect.get(mKey.apply(b)))).collect(Collectors.toList());
}
}
@FunctionalInterface
public interface Consumers<M, N> {
/**
* 消费函数
*
* @param m
* @param n
*/
void accept(M m, List<N> n);
}
}