java List数据封装Tree结构

阐述说明

该工具主要有以下几个特点
  1. 不使用递归: 该工具将list封装为tree结果的过程中,完成不涉及到递归方式来进行操作封装,借用map方式进行获取操作节点,避免树层级过多时嵌套多个循环来进行操作封装,该方式可以高效率完成节点封装为Tree树结构
  2. 使用lambda表达式: 工具中运用到了java8的新特性lambda表达式,主要的好处是可以很灵活接收各种list对象集合,可以对象属性情况解析为Tree的node节点对象,还有就是可以快速进行集合操作
  3. 代码简洁: 该工具不仅仅是可以高效率进行封装为Tree树结构,更重要的是,其代码简洁,运用方便,值得大家去借鉴和使用

工具相关源码

Tree的Node节点:该节点属性是按照vue的antd ui组件tree树属性进行设置,可以根据运用情况进行修改相关属性,或者使用继承方式也可以

import lombok.Data;
import java.util.ArrayList;
import java.util.List;

/**
 * a-tree树节点
 * @param <T>
 */
@Data
public class TreeNode<T> {

    public TreeNode() {
    }

    public TreeNode(T node, String key, String title, String parentKey) {
        this.node = node;
        this.key = key;
        this.title = title;
        this.parentKey = parentKey;
    }

    /**
     * 节点对象
     */
    private T node;
    /**
     * a-tree树key
     */
    private String key;
    /**
     * a-tree树标题
     */
    private String title;
    /**
     * a-tree树父节点key
     */
    private String parentKey;
    /**
     * a-tree树子节点
     */
    private List<TreeNode<T>> children = new ArrayList<>();


}


Tree封装工具:该工具提供两种方式调用,可以根据个人喜好来选择
import org.test.entity.TreeNode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * a-tree树工具
 */
public class TreeUtil {

    /**
     * List集合转为a-tree树状数据(调用方式一)
     * @param list 需要转为树状的集合
     * @param toTreeNode 对象转为TreeNode节点Function
     * @return
     */
    public static<T> List<TreeNode<T>> getTreeList(List<T> list, Function<T, TreeNode<T>> toTreeNode){
        //对象--封装-->树节点
        List<TreeNode<T>> treeNodeList = list.stream().map(toTreeNode).collect(Collectors.toList());
        return nodeToTree(treeNodeList);
    }



    /**
     * List集合转为a-tree树状数据(调用方式二)
     * @param list 需要转为树状的集合
     * @param key TreeNode的key对应对象的属性
     * @param title TreeNode的title对应对象的属性
     * @param parentKey TreeNode的parentKey对应对象的属性
     * @return
     */
    public static<T> List<TreeNode<T>> getTreeList(List<T> list, Function<T, String> key,Function<T,String> title,Function<T,String> parentKey){
        List<String> keys = list.stream().map(key).collect(Collectors.toList());
        List<String> titles = list.stream().map(title).collect(Collectors.toList());
        List<String> parentKeys = list.stream().map(parentKey).collect(Collectors.toList());
        //对象--封装-->树节点
        List<TreeNode<T>> treeNodeList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            TreeNode<T> treeNode = new TreeNode<>(list.get(i),keys.get(i),titles.get(i),parentKeys.get(i));
            treeNodeList.add(treeNode);
        }
        return nodeToTree(treeNodeList);
    }



    /**
     * 把list节点封装为树状数据
     * @param treeNodeList 需要转为tree树状的list集合
     * @param <T>
     * @return
     */
    private static<T> List<TreeNode<T>> nodeToTree(List<TreeNode<T>> treeNodeList){
        //把list对象存储到map中,方便后面用于树状拼接
        Map<String,TreeNode<T>> treeNodeMap = treeNodeList.stream().collect(Collectors.toMap(TreeNode::getKey,i->i));
        //连接树节点,封装为树状
        List<TreeNode<T>> data = new ArrayList<>();
        treeNodeList.forEach(val->{
            String pk =  val.getParentKey();
            TreeNode<T> parent = treeNodeMap.get(pk);
            if(parent == null){
                //该节点为顶级节点,直接添加到返回数据中
                data.add(val);
            }else {
                //该节点有父节点,则需添加到其父节点的子节点中
                parent.getChildren().add(val);
            }
        });
        return data;
    }

}
调用方式:比较简单灵活,可以将数据查询到的相关list传值到该工具中,即可封装为Tree结构了
	/**
     * 模拟需要封装的实体
     */
    @Data
    class Demo{
        private String id;
        private String name;
        private String parentId;
    }
    
    
    public static void main(String[] args) {
        List<Demo> list = new ArrayList<>();//模拟数据库查询到的相关数据
        TreeUtil.getTreeList(list, Demo::getId,Demo::getName,Demo::getParentId);//调用方式一
        TreeUtil.getTreeList(list,i->new TreeNode<>(i,i.getId(),i.getName(),i.getParentId())); //调用方式二
    }

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值