在一些管理系統中通常都會用到,會用到一些樹形數據,例如部門組織以及權限等數據,都得生成樹形數據,須要寫一些樹形數據生成工具,通常使用遞歸的方式,性能低下還可能會致使爆棧。通過分析和思考,我決定不採用遞歸的方式來編寫樹形數據的處理,最終選用hasMap來維護樹節點之間的關係。以權限樹爲例,作一個樹形數據工具類的設計。java
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for permission -- ---------------------------- DROP TABLE IF EXISTS `permission`; CREATE TABLE `permission` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '權限id', `name` varchar(32) NOT NULL COMMENT '權限名稱', `url` varchar(64) DEFAULT NULL COMMENT '資源url', `type` int(11) NOT NULL COMMENT '權限類型,1:模塊,2:菜單,3:url資源', `parent_id` int(11) NOT NULL DEFAULT '0' COMMENT '上級資源id', `icon` varchar(64) DEFAULT NULL COMMENT '菜單圖標', `sort` int(11) DEFAULT NULL COMMENT '排序', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間', `operator` varchar(32) DEFAULT NULL COMMENT '操做者', `level` int(11) NOT NULL DEFAULT '0', `code` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;
java bean的設計依據數據庫的表來進行設計,構造方法以及get、set方式使用lombok註解。mysql
package com.lk.permission.common.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import lombok.experimental.Accessors; import java.util.ArrayList; import java.util.Date; import java.util.List; //@SuppressWarnings("serail") @ToString @NoArgsConstructor @AllArgsConstructor @Data @Accessors(chain = true) public class Permission { /** 權限ID */ private Integer id; /** 權限名稱 */ private String name; /** 權限編碼 */ private String code; /** 菜單圖標 */ private String icon; /** 資源類型 */ private Integer type; /** 資源地址 */ private String url; /** 層級 */ private Integer level; /** 上層ID */ private Integer parentId; /** 排序 */ private Integer sort; /** 建立時間 */ private Date createTime; /** 更新時間 */ private Date updateTime; /** 操做人員 */ private String operator; /** 下級權限 */ private List<Permission> subPermissions = new ArrayList<>(); }
我只提供一個實現思路,具體可根據本身業務實現,經過hasMap方式,一個是性能有了較大的提高,另外一個不用擔憂爆棧的風險。下面維護關係已經給出,可進行適當的改造來實現本身具體業務需求。sql
package com.lk.permission.system.service.impl; import com.lk.permission.common.pojo.Permission; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class TreeService { private Map<Integer,Permission> map; private List<Permission> permissions; /** * 初始化多叉樹 * @param permissions */ TreeService(List<Permission> permissions){ this.permissions = permissions; this.map = new HashMap<>(); for (Permission permission : permissions){ this.map.put(permission.getId(),permission); } createTree(); } /** * 建立多叉樹 */ private void createTree(){ for (Permission permission : this.permissions){ if (this.map.containsKey(permission.getParentId())){ this.map.get(permission.getParentId()).getSubPermissions().add(permission); System.out.println(permission.toString()); } } } /** * 根據層級獲取多叉樹 * @param level * @return */ List<Permission> getPermissionsByLevel(Integer level){ return this.permissions.parallelStream().filter(permission -> permission.getLevel() == level).collect(Collectors.toList()); } /** * 根據樹的id獲取多叉樹 * @param id * @return */ Permission getPermissionById(Integer id){ return this.map.get(id); } /** * 向多叉樹添加子節點 * @param permission */ public void addChild(Permission permission){ if (this.map.containsKey(permission.getParentId())){ ((Permission)this.map.get(permission.getParentId())).getSubPermissions().add(permission); } this.map.put(permission.getId(),permission); } }