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"
		}]
	}]
}]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章