在一些管理系统中通常都会用到,会用到一些树形数据,例如部门组织以及权限等数据,都得生成树形数据,须要写一些树形数据生成工具,通常使用递归的方式,性能低下还可能会致使爆栈。通过分析和思考,我决定不采用递归的方式来编写树形数据的处理,最终选用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); } }