自定义List转化Tree 工具类 Hutool TreeUtil工具类

TreeUtil


import java.util.*;
import java.util.function.ToIntFunction;

/**
 * 树型工具
 */
public final class TreeUtil {
    private TreeUtil() {
    }

    /**
     * 列表转树形
     *
     * @param <T> {@link TreeModel}
     * @return 树
     */
    public static <T extends TreeModel<T>> List<T> listToTree(List<T> list) {
        return listToTree(list, null);
    }

    /**
     * 列表转树形 带排序
     *
     * @param list    所有list
     * @param compare {@link Comparator#comparingInt(ToIntFunction)}
     * @param <T>     {@link TreeModel}
     * @return 树
     */
    public static <T extends TreeModel<T>> List<T> listToTree(List<T> list, Comparator<T> compare) {
        //all groupingBy methods end up using the same map.merge() that rejects null keys
        //        Stream<T> stream = list.stream();
        Map<String, List<T>> groupMap = new HashMap<>();
        Map<String, T> idMap = new HashMap<>();
        List<T> result = new ArrayList<>();

        //按parent分组
        for (T t : list) {
            idMap.put(t.getId(), t);
            List<T> children = groupMap.computeIfAbsent(t.getParentId(), k -> new ArrayList<>());
            children.add(t);
        }
        //排序
        if (compare != null) {
            for (HashMap.Entry<String, List<T>> entry : groupMap.entrySet()) {
                String key = entry.getKey();
                List<T> value = entry.getValue();
                value.sort(compare);
                matchChildren(key, value, idMap, result);
            }
            result.sort(compare);
        }
        //不排序
        else {
            for (HashMap.Entry<String, List<T>> entry : groupMap.entrySet()) {
                String key = entry.getKey();
                List<T> value = entry.getValue();
                matchChildren(key, value, idMap, result);
            }
        }
        return result;
    }


    /**
     * 给children无父级按根级处理
     */
    private static <T extends TreeModel<T>> void matchChildren(String key, List<T> value, Map<String, T> idMap, List<T> result) {
        T t = idMap.get(key);
        if (t != null) {
            t.setChildren(value);
        } else {
            result.addAll(value);
        }
    }
}

TreeModel


/**
 * 树形
 */
public interface TreeModel<T> {

    /**
     * 主键id
     * @return
     */
    String getId();

    /**
     * 父id
     * @return
     */
    String getParentId();

    /**
     * 设置子数据集
     * @param children
     * @return
     */
    T setChildren(List<T> children);
}

Menu 菜单类

@Data
//链式访问,该注解设置chain=true,生成setter方法返回this(也就是返回的是对象),代替了默认的返回void。
@Accessors(chain = true)
public class Menu implements TreeModel<Menu> {

    private String id;

    private String parentId;

    private String url;

    private Integer sort;

    /**
     * 子节点
     */
    private List<Menu> children;

    public Menu() {
    }

    public Menu(String id, String parentId, String url, Integer sort) {
        this.id = id;
        this.parentId = parentId;
        this.url = url;
        this.sort = sort;
    }
}

测试

public class MenuDemo {
    public static void main(String[] args) {
        ArrayList<Menu> list = new ArrayList<>();
        list.add(new Menu("1", "0", "/abc", 1));
        list.add(new Menu("2", "1", "/aaa", 5));
        list.add(new Menu("3", "1", "/bbb", 2));
        list.add(new Menu("4", "2", "/ccc", 1));
        list.add(new Menu("5", "0", "/ddd", 15));
        list.add(new Menu("6", "5", "/eee", 14));
        list.add(new Menu("7", "6", "/fff", 10));
        list.add(new Menu("8", "6", "/ggg", 15));

        List<Menu> menus = TreeUtil.listToTree(list);
        System.out.println(JSON.toJSONString(menus));

        List<Menu> menusSort = TreeUtil.listToTree(list, Comparator.comparing(Menu::getSort));
        System.out.println(JSON.toJSONString(menusSort));

    }

}

Hutool-TreeUtil

City 类

@Data
public class City {
    private Integer id;
    private String cityName;
    private Integer parentId;
    private List<City> children;

    public City(Integer id, String cityName, Integer parentId) {
        this.id = id;
        this.cityName = cityName;
        this.parentId = parentId;
    }
}

测试代码

public class CityDemo {

    public static void main(String[] args) {
        List<City> cities = CollUtil.newArrayList();
        cities.add(new City(1, "广东省", 0));
        cities.add(new City(2, "广州市", 1));
        cities.add(new City(3, "南沙区", 2));
        cities.add(new City(4, "万顷沙镇", 3));
        cities.add(new City(5, "黄阁镇", 3));
        cities.add(new City(6, "湖南省", 0));
        cities.add(new City(7, "长沙市", 6));
        cities.add(new City(8, "芙蓉区", 7));
        // 2.配置
        TreeNodeConfig config = new TreeNodeConfig();

        // 默认为id可以不设置
        config.setIdKey("id");
        //  默认为parentId可以不设置
        config.setParentIdKey("parentId");
        //  最大递归深度
        config.setDeep(3);
        // // 默认为children不用设置
        config.setChildrenKey("children");
        // 3.转树,Tree<>里面泛型为id的类型
        List<Tree<Integer>> build = TreeUtil.build(cities, 0, config, (object, tree) -> {
            // 也可以使用 tree.setId(object.getId());等一些默认值
            Field[] fields = ReflectUtil.getFieldsDirectly(object.getClass(), true);
            for (Field field : fields) {
                String fieldName = field.getName();
                Object fieldValue = ReflectUtil.getFieldValue(object, field);
                tree.putExtra(fieldName, fieldValue);
            }
            //如果不想全部字段可以按照下面的写法添加
            /*tree.putExtra("id", object.getId());
            tree.putExtra("parentId", object.getParentId());
            tree.putExtra("cityName", object.getCityName());*/
        });
        System.out.println(JSON.toJSON(build));
    }
}
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值