java-jsTree通用的树生成代码v2.0

前言:如果字段与demo完全不同,且无法修改为demo中的匹配字段,只需修改以下部分即可
一、修改排序字段
TreeNodes类的"level"改为相应的字段
private final static String LEVEL= "level";–>private final static String LEVEL= "myLevel";
在这里插入图片描述
已实现排序,亦可将Tools类里Collections.sort(treeNodes);//排序代码注释,位置在50~60行之前
在这里插入图片描述
二、自定义树包含的字段
对changeKey对象进行扩展,可以为树添加更多的字段
在这里插入图片描述
三、自定义子树名称、ID及父ID
在这里插入图片描述

  1. 引入jar包
    maven项目导入jar包
    非maven项目手动下载指定的包,并导入项目内
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
  1. 测试菜单列表
package ac.cn.chm.base.entity;

import lombok.Data;

@Data//或手动创建getter、setter方法
public class Menu {
    private String menuId;
    private String menuName;
    private Integer menuLevel;
    private String parentId;
    private String menuIcon;

    public Menu(String menuId, String menuName, Integer menuLevel, String parentId, String menuIcon) {
        this.menuId = menuId;
        this.menuName = menuName;
        this.menuLevel = menuLevel;
        this.parentId = parentId;
        this.menuIcon = menuIcon;
    }
}

  1. 通用校验接口

import java.util.Collection;
import java.util.Map;

public class CheckUtils {

    public static void main(String[] args) {
        double[] a = new double[0];
        System.out.println(isEmpty(a));
//        System.out.println("list="+isEmpty(new ArrayList<String>()));
//        System.out.println("list="+isEmpty(new HashSet<String>()));
    }

    public static boolean isEmpty(Object o) {
        if (o == null) {
            return true;
        } else {
            if (o instanceof String && o.toString().trim().equals("")) {        //字符串判断
                return true;
            } else if (o instanceof Iterable && ((Collection) o).size() <= 0) { //判断set和list
                return true;
            } else if (o instanceof Map && ((Map) o).size() == 0) {             //map判断
                return true;
            } else if (o instanceof Object[] && ((Object[]) ((Object[]) o)).length == 0) {//object判断
                return true;
            } else if (isEmptyBasicDataArray(o)) {              //基础数据类型数组判断
                return true;
            }
            return false;
        }
    }
    /**
     * 判断传入所有可变参数是否有一个为空
     * @param o
     * @return
     */
    public static boolean isOneEmpty(Object ... o){
        for (Object obj :o ) {
            if(isEmpty(obj)){//有一个为空,符合条件
                return true;
            }
        }
        return false;
    }

    /**
     * 判断传入所有可变参数是否都为空
     * @param o
     * @return
     */
    public static boolean isAllEmpty(Object ... o){
        for (Object obj :o ) {
            if(!isEmpty(obj)){//有一个不为空,则不符合条件
                return false;
            }
        }
        return true;
    }

    /**
     * 判断传入可变参数是否有一个参数不为空
     * @param o
     * @return
     */
    public static boolean isOneNotEmpty(Object ... o){
        for (Object obj :o ) {
            if(!isEmpty(obj)){//有一个不为空,符合条件
                return true;
            }
        }
        return false;
    }

    /**
     * 判断传入所有可变参数是否都非空
     * @param o
     * @return
     */
    public static boolean isAllNotEmpty(Object ... o){
        for (Object obj :o ) {
            if(isEmpty(obj)){//有一个为空,则不符合条件
                return false;
            }
        }
        return true;
    }
    /**
     * 判断基础数据类型是否非空
     * @param o
     * @return
     */
    public static boolean isNotEmpty(Object o ){
        return !isEmpty(o);
    }

    /**
     * 校验基础数据类型数组是否为空
     *
     * @param o
     * @return
     */
    public static boolean isEmptyBasicDataArray(Object o) {
        if (o == null) {
            return true;
        } else {
            if (o instanceof int[] && ((int[]) ((int[]) o)).length == 0) {
                return true;
            } else if (o instanceof long[] && ((long[]) ((long[]) o)).length == 0) {
                return true;
            } else if (o instanceof byte[] && ((byte[]) ((byte[]) o)).length == 0) {
                return true;
            } else if (o instanceof char[] && ((char[]) ((char[]) o)).length == 0) {
                return true;
            } else if (o instanceof double[] && ((double[]) ((double[]) o)).length == 0) {
                return true;
            } else if (o instanceof float[] && ((float[]) ((float[]) o)).length == 0) {
                return true;
            } else if (o instanceof short[] && ((short[]) ((short[]) o)).length == 0) {
                return true;
            } else if (o instanceof boolean[] && ((boolean[]) ((boolean[]) o)).length == 0) {
                return true;
            }
        }
        return false;
    }


    /**
     * 判断基础数据类型数组是否非空
     * @param o
     * @return
     */
    public static boolean isNotEmptyBasicDataArray(Object o){
        return !isEmptyBasicDataArray(o);
    }

    /**
     * 判断传入可变数组是否有一个为空
     * @param o
     * @return
     */
    public static boolean isOneEmptyBasicDataArray(Object ... o){
        for (Object obj :o ) {
            if(isEmptyBasicDataArray(obj)){//有一个符合条件即可
                return true;
            }
        }
        return false;
    }
    /**
     * 判断传入可变数组是否有一个非空
     * @param o
     * @return
     */
    public static boolean isOneNotEmptyBasicDataArray(Object ... o){
        for (Object obj :o ) {
            if(!isEmptyBasicDataArray(obj)){//有一个符合条件即可
                return true;
            }
        }
        return false;
    }

    /**
     * 判断传入可变数组是否全部为空
     * @param o
     * @return
     */
    public static boolean isAllEmptyBasicDataArray(Object ... o){
        for (Object obj :o ) {
            if(!isEmptyBasicDataArray(obj)){//有一个不为空,则不符合条件
                return false;
            }
        }
        return true;
    }
    /**
     * 判断传入可变数组是否全部为空
     * @param o
     * @return
     */
    public static boolean isAllNotEmptyBasicDataArray(Object ... o){
        for (Object obj :o ) {
            if(isEmptyBasicDataArray(obj)){//有一个不为空,则不符合条件
                return false;
            }
        }
        return true;
    }
}

  1. 创建TreeNodes实体类
import ac.cn.chm.tools.CheckUtils;
import com.alibaba.druid.sql.visitor.functions.Char;
import lombok.Data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@Data
public class TreeNodes extends HashMap implements Comparable<TreeNodes> {//实现Comparable接口,实现根据level排序
	public final static String LEVEL= "level";          //节点的层级         必须字段
    public final static String CHILDREN ="children";    //子树            必须字段
    public final static String ID = "id";               //节点的ID         必须字段
    public final static String PID = "pId";             //节点的父ID      必须字段

    public final static String ICON = "icon";           //节点图标          非必须
    public final static String NAME = "name";           //节点名称          非必须

    public TreeNodes(){
        this.put("children",new ArrayList<TreeNodes>());//保存子树
    }

    public Integer getInt(String key){
        Object o = this.get(key);
        if (o instanceof Integer ||o instanceof Short ||o instanceof Long ||o instanceof Byte) {
            return (Integer)o;
        }else{
            try{
                return Integer.valueOf((String)o);
            }catch (Exception e){
                System.out.println("level字段无法转换为整型数字");
            }
        }
        return 1;//不会到这来,会先抛出异常
    }

    public String getStr(String key){
        Object o = this.get(key);
        if (o instanceof Integer ||o instanceof Short ||o instanceof Long ||o instanceof Byte) {
            return String.valueOf(o);
        }else{
            return (String)o;
        }
    }
    @Override
    public int compareTo(TreeNodes tn) {
        //如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
        //1排在当前的后面//-1排在当前的前面
        int big = 1, small = -1, eq = 0;
        if(CheckUtils.isEmpty(tn)){
            return big;
        }
        Integer thisLevel = this.getInt(LEVEL);
        Integer tnLevel = tn.getInt(LEVEL);
        if (CheckUtils.isEmpty(tnLevel)) {
            return big;
        } else if (CheckUtils.isEmpty(thisLevel)) {
            return small;
        } else if (tnLevel < thisLevel) {
            return big;
        } else if (tnLevel > thisLevel) {
            return small;
        }
        return eq;
    }
}
  1. 转接类的编写
public class Tools {

    public static void main(String[] args) {//测试用例

        Map<String,String> changeKey = new HashMap<>();
        {//必须字段
            changeKey.put("menuId", TreeNodes.ID);//将“menuId”转换为TreeNodes.ID
            changeKey.put("menuLevel", TreeNodes.LEVEL);
            changeKey.put("parentId", TreeNodes.PID);
        }
        {//非必须字段
            changeKey.put("menuName", TreeNodes.NAME);
            changeKey.put("menuIcon", TreeNodes.ICON);
        }
        //可自定义更多字段

        List<Menu> pts = getMenuList();//模拟获取列表信息
        List<TreeNodes> list = Tools.formatTree(pts, changeKey);//将列表转换为树
        System.out.println(JSON.toJSONString(list));
    }

    public static List<Menu> getMenuList(){
        List<Menu> list = new ArrayList<>();
        list.add(new Menu("1","基础管理",1,"0","base-icon"));
        list.add(new Menu("2","用户管理",2,"1","user-icon"));
        list.add(new Menu("6","添加菜单",3,"3","menu-add-icon"));
        list.add(new Menu("7","编辑菜单",3,"3","menu-edit-icon"));
        list.add(new Menu("3","菜单管理",2,"1","menu-icon"));
        list.add(new Menu("4","添加用户",3,"2","user-add-icon"));
        list.add(new Menu("8","添加用户并分配菜单",4,"4","user-menu-add-icon"));
        list.add(new Menu("5","编辑用户",3,"2","user-edit-icon"));
        return list;
    }


    /**
     * @param list 树的内容,需要按照level从小到大进行排序,否则无法获取到第一个层级,且易造成树的分支丢失
     * @param keys
     * @param <T>
     * @return
     */
    public static <T> List<TreeNodes> formatTree(List<T> list, Map<String,String> keys) {
        if (list == null || list.size() <= 0) {
            return new ArrayList<>();
        }

        //List<TreeNodes> treeNodes = getTreeNodes(list,keys);//保存多余的字段
        List<TreeNodes> treeNodes = getTreeNodesByMap(list,keys);//不保存多余的字段

        Collections.sort(treeNodes);//排序

        Map<String, List<TreeNodes>> map = new HashMap<>();//change,修改List为指定的类型
        //转换字段
        List<TreeNodes> root = null;//根目录 //change,修改List为指定的类型

        for (TreeNodes current : treeNodes) {//change,修改List为指定的类型
            {//添加当前元素到指定级别
                String level = current.getStr(TreeNodes.LEVEL);//change,修改获取层级的方法
                if (!map.containsKey(level)) {//不存在,先添加list
                    map.put(level, new ArrayList<TreeNodes>());//change,修改List为指定的类型
                }
                List<TreeNodes> arr = map.get(level);//当前层级//change,修改List为指定的类型
                arr.add(current);
                if (root == null) {//表示是第一级
                    root = arr;
                }
            }

            //将当前元素添加到父级的子元素列表里
            {
                List<TreeNodes> parentTree = map.get(String.valueOf(current.getInt(TreeNodes.LEVEL) - 1));//change,修改List、获取层级的方法
                if (parentTree == null) {
                    continue;
                }
                for (TreeNodes parent : parentTree) {//change,修改List为指定的类型
                    if (parent.get(TreeNodes.ID).equals(current.get(TreeNodes.PID))) {//如果找不到父级,则为异常数据,抛弃   //change,修改上下级关联的判断依据
                        ((List<TreeNodes>)parent.get(TreeNodes.CHILDREN)).add(current);
                        break;
                    }
                }
            }
        }

        return root;
    }

    /**
     * 更新字段
     */
    public static String changeKey(String json, Map<String,String> keys) {


        if (CheckUtils.isOneEmpty(json,keys)) {
            return "";
        }
        for (Map.Entry<String,String> entry : keys.entrySet()) {
            json = json.replaceAll(entry.getKey(),entry.getValue());
        }
        return json;
    }

    /**
     * 获取TreeNodes,不去除多余字段
     */
    public static <T>  List<TreeNodes> getTreeNodes(List<T> list, Map<String,String> keys) {

        String jsonStr = JSON.toJSONString(list);
        jsonStr = changeKey(jsonStr, keys);//change,不改变格式,不需要这段代码,直接删除
        List<TreeNodes> treeNodes = listClone(jsonStr, TreeNodes.class);//change,不改变格式,不需要这段代码,直接删除
        return treeNodes;
    }
    /**
     * 根据keys里的字段获取TreeNodes
     */
    public static <T> List<TreeNodes> getTreeNodesByMap(List<T> list,Map<String,String> keys){
        if (CheckUtils.isOneEmpty(list,keys)) {
            return null;
        }
        String json = JSON.toJSONString(list);
        List<JSONObject> objects = listClone(list,JSONObject.class);
        List<TreeNodes> nodes = new ArrayList<>();
        for (JSONObject t: objects  ) {
            for (Map.Entry<String,String> entry : keys.entrySet()) {
                TreeNodes treeNodes = new TreeNodes();
                treeNodes.put(entry.getValue(),t.get(entry.getKey()));
                nodes.add(treeNodes);
            }
        }
        return nodes;
    }

    /**
     * 将一个对象的列表转换为另一个对象的列表
     *
     * @param k
     * @param clazz
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T, K> List<T> listClone(List<K> k, Class<T> clazz) {
        List<T> list = JSONArray.parseArray((JSONArray.toJSON(k)).toString(), clazz);
        return list;
    }

    /**
     * 将json格式的字符串转换为指定对象的列表
     *
     * @param str
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> listClone(String str, Class<T> clazz) {
        List<T> list = JSONArray.parseArray(str, clazz);
        return list;
    }
}
  1. 运行结果
[{
	"level": 1,
	"icon": "base-icon",
	"name": "基础管理",
	"pId": "0",
	"id": "1",
	"children": [{
		"level": 2,
		"icon": "user-icon",
		"name": "用户管理",
		"pId": "1",
		"id": "2",
		"children": [{
			"level": 3,
			"icon": "user-add-icon",
			"name": "添加用户",
			"pId": "2",
			"id": "4",
			"children": [{
				"children": [],
				"level": 4,
				"icon": "user-menu-add-icon",
				"name": "添加用户并分配菜单",
				"pId": "4",
				"id": "8"
			}]
		}, {
			"children": [],
			"level": 3,
			"icon": "user-edit-icon",
			"name": "编辑用户",
			"pId": "2",
			"id": "5"
		}]
	}, {
		"level": 2,
		"icon": "menu-icon",
		"name": "菜单管理",
		"pId": "1",
		"id": "3",
		"children": [{
			"children": [{
				"children": [],
				"level": 4,
				"icon": "user-menu-add-icon",
				"name": "添加用户并分配菜单",
				"pId": "4",
				"id": "8"
			}],
			"level": 3,
			"icon": "user-add-icon",
			"name": "添加用户",
			"pId": "2",
			"id": "4"
		}, {
			"children": [],
			"level": 3,
			"icon": "user-edit-icon",
			"name": "编辑用户",
			"pId": "2",
			"id": "5"
		}]
	}]
}]

猜你喜欢

转载自blog.csdn.net/qq_25598453/article/details/89239795