Java工具类 - 将List转换为树状结构

Posted Gendan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java工具类 - 将List转换为树状结构相关的知识,希望对你有一定的参考价值。

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**

  • @program: myUtil
  • @description: 工具类 - 树状结构生成
  • @author: syf
  • @create: 2021-06-15 10:38
    */

public class TreeModel<T> {

/**
 * 上级字段名称
 */
private Function<T, ?> superColumn;
/**
 * 当前比对字段
 */
private Function<T, ?> column;
/**
 * 列表接收字段名
 */
private BiConsumer<T, List<T>> children;
/**
 * 数据列表
 */
private List<T> list;
/**
 * 数据解除关联性使用的对象
 */
private Supplier<T> decoupling;
/**
 * 私有化工具类
 */
private TreeModel() {
}
/**
 * 初始化载入树状工具类
 *
 * @param list        需要整合的数据列表
 * @param superColumn 上级字段(对象::字段get方法)
 * @param column      本级字段(对象::字段get方法)
 * @param children    下级数据存储字段(对象::字段set方法)
 * @return 树状工具类
 */
public static <R> TreeModel<R> load(List<R> list, Function<R, ?> superColumn,
                                    Function<R, ?> column, BiConsumer<R, List<R>> children) {
    TreeModel<R> treeModel = new TreeModel<>();
    treeModel.setSuperColumn(superColumn)
            .setColumn(column)
            .setChildren(children)
            .setList(list);
    return treeModel;
}
/**
 * 获取树状数据(不解除原集合中对象与树状集合对象的关联)
 *
 * @param initValue 根数据
 * @return 树状数据数据列表
 */
public List<T> getTree(Object initValue) {
    List<T> tree = treeAll(initValue);
    if (tree != null && tree.size() > 0) {
        return tree.stream().filter(ls -> initValue.equals(superColumn.apply(ls))).collect(Collectors.toList());
    }
    return tree;
}
/**
 * 获取树状数据(解除原集合中对象与树状集合对象的关联)
 *
 * @param initValue  根数据
 * @param decoupling 解除关联对象(对象::new)
 * @return 树状数据数据列表
 */
public List<T> getTree(Object initValue, Supplier<T> decoupling) {
    this.setDecoupling(decoupling);
    return tree(initValue);
}
/**
 * 获取树状数据
 *
 * @param initValue 根数据
 * @return 树状数据
 */
private List<T> treeAll(Object initValue) {
    if (list == null || list.size() < 1) {
        return list;
    }
    List<T> collect = list.stream().filter(f -> initValue.equals(superColumn.apply(f))).collect(Collectors.toList());
    if (collect.size() < 1) {
        return null;
    }
    collect.forEach(c -> children.accept(c, treeAll(column.apply(c))));
    return collect;
}
private List<T> tree(Object o) {
    List<T> childrenList = new ArrayList<>();
    if(o == null){
        return childrenList;
    }
    for (T entity : list) {
        if (o.equals(superColumn.apply(entity))) {
            T now = decoupling.get();
            copy(entity, now);
            childrenList.add(now);
        }
    }
    for (T cs : childrenList) {
        children.accept(cs, tree(column.apply(cs)));
    }
    return childrenList;
}
/**
 * 将source中的属性赋值给target
 * @param source    数据来源类
 * @param target    数据接收类
 */
private void copy(T source, T target) {
    if (source == null) {
        throw new NullPointerException("dataSource");
    }
    if (target == null) {
        target = decoupling.get();
    }
    Field[] sourceFields = source.getClass().getDeclaredFields();
    Field[] targetFields =[期货](https://www.gendan5.com/p/2021-06-11/248014.html) target.getClass().getDeclaredFields();
    Map<String, Object> sourceMap = new HashMap<>(sourceFields.length);
    try {
        for (Field field : sourceFields) {
            if (Modifier.isFinal(field.getModifiers())) {
                continue;
            }
            field.setAccessible(true);
            sourceMap.put(field.getName(), field.get(source));
        }
        for (Field field : targetFields) {
            Object o = sourceMap.get(field.getName());
            if (o == null) {
                continue;
            }
            field.setAccessible(true);
            field.set(target, o);
        }
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}
private TreeModel<T> setSuperColumn(Function<T, ?> superColumn) {
    if (superColumn == null) {
        throw new NullPointerException("superColumn");
    }
    this.superColumn = superColumn;
    return this;
}
private TreeModel<T> setColumn(Function<T, ?> column) {
    if (column == null) {
        throw new NullPointerException("column");
    }
    this.column = column;
    return this;
}
private TreeModel<T> setChildren(BiConsumer<T, List<T>> children) {
    if (children == null) {
        throw new NullPointerException("children");
    }
    this.children = children;
    return this;
}
private void setList(List<T> list) {
    if (list == null || list.size() < 1) {
        throw new NullPointerException("list");
    }
    this.list = list;
}
private void setDecoupling(Supplier<T> decoupling) {
    if (decoupling == null) {
        throw new NullPointerException("decoupling");
    }
    this.decoupling = decoupling;
}

}

以上是关于Java工具类 - 将List转换为树状结构的主要内容,如果未能解决你的问题,请参考以下文章

java常用的工具类

C++里怎样用map将枚举类转换到string类

php7将二维数组转为树状数组

将组织结构转换为树状json

JAVA中List转换String,String转换List,Map转换String,String转换Map之间的转换工具类(调优)

python用[]将int转换为list