1. 程式人生 > 實用技巧 >Java 處理樹形結構資料

Java 處理樹形結構資料

在寫專案中後臺管理可能需要一些動態選單樹,所以在此記錄一下先看下json資料格式

{
  "reason": "SUCCESS",
  "code": 200,
  "data": [
    {
      "id": "5",
      "labelName": "測試4",
      "parentId": null,
      "cheaked": "false",
      "children": [
        {
          "id": "6",
          "labelName": "標籤測試",
          "parentId": "5",
          
"cheaked": "false", "children": [] }, { "id": "11", "labelName": "二級", "parentId": "5", "cheaked": "false", "children": [] } ] }, { "id": "7", "labelName": "測試五級", "parentId": null,
"cheaked": "false", "children": [ { "id": "8", "labelName": "測試四級", "parentId": "7", "cheaked": "false", "children": [ { "id": "9", "labelName": "測試三級", "parentId": "8",
"cheaked": "false", "children": [] } ] } ] }, { "id": "10", "labelName": "一級", "parentId": null, "cheaked": "false", "children": [] } ], "message": null }

1.先分析一下:當一行資料parentId是空的 肯定是第一層選單,若有一行parentId是這行的Id那麼就是這行的孩子

實體類

package com.cmbchina.ccd.itpm.label.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author zly
 * @Date 2019/9/27 14:17
 */
@Entity
@Table(name = "asset_label")
public class Label implements Serializable{
    @Id
    private String id;
    private String labelName;
    private String parentId;
    private String cheaked;
    @Transient
    private List<Label> children = new ArrayList<>();

    public Label(String id, String labelName, String parentId, List<Label> children) {
        this.id = id;
        this.labelName = labelName;
        this.parentId = parentId;
        this.children = children;
    }

    public Label() {
    }
    public String getCheaked() {
        return cheaked;
    }

    public void setCheaked(String cheaked) {
        this.cheaked = cheaked;
    }

    @Override
    public String toString() {
        return "Label{" + "id='" + id + '\'' + ", labelName='" + labelName + '\'' + ", parentId='" + parentId + '\'' +
               ", cheaked='" + cheaked + '\'' + ", children=" + children + '}';
    }

    public List<Label> getChildren() {
        return children;
    }

    public void setChildren(List<Label> children) {
        this.children = children;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getLabelName() {
        return labelName;
    }

    public void setLabelName(String labelName) {
        this.labelName = labelName;
    }

    public String getParentId() {
        return parentId;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }
}

建表語句

CREATE TABLE `asset_label` (
  `id` int(255) NOT NULL AUTO_INCREMENT COMMENT '選單Id',
  `labelName` varchar(255) DEFAULT NULL COMMENT '選單名稱',
  `parentId` varchar(255) DEFAULT NULL COMMENT '父級ID',
  `cheaked` varchar(255) DEFAULT 'false' COMMENT '是否勾選',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

重點來了 邏輯程式碼處理

 public R getAll() {
        List<Label> labelList = labelDao.getLabelList();
        return R.ok(makeTreeLabelDto(labelList));
    }

    //構建選單樹
    public List<Label> makeTreeLabelDto(List<Label> labelList) {
        List<Label> firstLabelDto = new ArrayList<>();
        Map<String, Label> labelMap = new HashMap<>();
        for (Label label : labelList) {
            labelMap.put(label.getId(), label);
            //判斷是否有父節點 (沒有父節點本身就是個父選單)
            if (label.getParentId() == null) {
                firstLabelDto.add(label);
            }
            //找出不是父級選單的且集合中包括其父選單ID
            if (label.getParentId() != null && labelMap.containsKey(label.getParentId())) {
                labelMap.get(label.getParentId()).getChildren().add(label);
            }
        }
        return firstLabelDto;
    }
 labelDao.getLabelList()這個方法就是將資料庫所有資料查詢出來沒有貼出主要看構建樹形結構的邏輯程式碼
這樣就可以實現文章開頭中的資料格式