java list转为树形结构

废话不多,java 中list转树

entity:


@Data
@ToString
public class User {

    /**
     * 用户id
     */
    private Long id;

    /**
     * 用户名
     */
    private String name;

    /**
     * 父id,即上级id
     */
    private Long parentId;
    
    /**
     * 排名
     */
    private Short orderNumber;
    
    /**
     * 子节点列表,即直系下级列表
     */
    private List<User> children;

    /**
     * 构造函数
     * @param id
     * @param name
     * @param parentId
     */
    public User(Long id, String name, Long parentId) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
    }
}


第一种:使用2次for循环遍历list数据
原理:通过for循环是遍历所有数据,将根节点的数据加到树列表中,接着通过第二次for循环寻找所有元素的子节点

public List<User> listToTree1() {
    List<User> list = list();
    List<User> tree = new ArrayList<>();
    for (User user : list) {
        //找到根节点
        if (user.getParentId() == null || user.getParentId().equals(0L)) {
            tree.add(user);
        }
        List<User> children = new ArrayList<>();
        //再次遍历list,找到user的子节点
        for (User node : list) {
            if (node.getParentId().equals(user.getId())) {
                children.add(node);
            }
        }
        user.setChildren(children);
    }
    return tree;
}


第二种:使用递归

public List<User> listToTree2() {
    List<User> list = list();
    List<User> tree = new ArrayList<>();
    for (User user : list) {
        //找到根节点
        if (user.getParentId() == null || user.getParentId().equals(0L)) {
            tree.add(findChildren(user, list));
        }
    }
    return tree;
}

/**
    * 查找user的子节点
    * @param user
    * @param list
    * @return
    */
private User findChildren(User user, List<User> list) {
    List<User> children = new ArrayList<>();
    for (User node : list) {
        if (node.getParentId().equals(user.getId())) {
            //递归调用
            children.add(findChildren(node, list));
        }
    }
    user.setChildren(children);
    return user;
}


原理:递归使用了2个函数,第一个listToTree2函数作用仅仅只是为了找到根节点,递归的函数是findChildren,这个函数会从list中查找属于user的子节点列表并设置到user中

第三种,使用stream 注意Jdk1.8及以上才支持

/* 另一种形式 */
public List<User> listToTree2(Integer parentId) {
List<User> list = this.list(new QueryWrapper<User>().lambda()
                    .eq(!Objects.isNull(parentId),parentId::getParentId,parentId))
if (isNotEmpty(list)) {
    // 递归获取菜单树形结构
    // 获取父节点,说明:父节点的parentId都是1(根节点是0)说明,这里的userId是传过来的参数,如果为空,就查询多个用户的结果,否则查询单个用户的树
    result = list.stream().filter(m -> 
            if (userId == null) {
                   return  1 == m.getParentId() ;
                } else {
                    return 0 == p.getParentId() && userId.equals(p.getUserId());
                }
            ).sorted(Comparator.comparingInt(m -> (m.getOrderNumber() == null ? 0 : m.getOrderNumber())))
            .peek(
            (m) -> m.setChildren(getChildren(m, list))
    ).collect(Collectors.toList());
 }
}
/**
* 递归获取子节点
**/
private List<User> getChildren(User m, List<User> list) {
   // 子节点parentId = 父节点ID
   return list.stream().filter(m1 -> m.getId().equals(m1.getParentId()))
           .sorted(Comparator.comparingInt(m -> (m.getOrderNumber() == null ? 0 : m.getOrderNumber())))
           .peek(m1 -> m1.setChildren(getChildren(m1, list))).collect(Collectors.toList());
}

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朝闻道-夕死可矣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值