树形结构设计总结,对于像部门,权限这样

1.树形结构三要素:
parentId:父节点id;
level:设计模式父节点的id+level。顶级节点的level默认值0;
seq:同一层级排序。
2.遍历:
主要思路:同一层级的节点保存在key为level的map结构中。这样就可以通过level拿到所有的子节点。
3.树形结构修改
1是root节点,1下有两个节点2,3。2下有一个节点4。4下有一个节点5.
那么修改规则如下:将4放到3下面。同时更新4的子节点的level。
思路:
(1)创建两个对象before,after来分别表示更新之前4的信息。
before:0.1.2 after 0.1.3
(2)通过before的id拿到ParentId为id的所有子节点。
(3)遍历自己点集合。
  将子节点的level的前缀删除了before的level剩下就是层次结构中不动的部分 childLevel。
 newLevel = after.getLevel()+childLevel;即最新的level。
 子节点5level 0.1.2.4。删除修改之前父节点level。剩下4;
 4结合修改之后的Level即0.1.3生成新的level:0.1.3.4即最新level.
package com.lai.tree.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.lai.tree.common.LevelUtil;
import com.lai.tree.pojo.Dept;
import com.lai.tree.pojo.DeptLevelDto;

public class DeptService {
	
	public static void main(String[] args) throws Exception {
		DeptService deptService = new DeptService();
//		getLevelDept(deptService);
		
		changeLevelDept(deptService);
		
//		deleteLevelDept(deptService);
	}
	
	private static void changeLevelDept(DeptService deptService) throws Exception {
		List<Dept> levelDeptList = deptService.getLevelDept();
		//将id为4的部门挂到id为1上面
		Dept parentDept = new Dept();
		parentDept.setId(1);
		parentDept.setLevel(LevelUtil.ROOT);
		
		Dept before =  deptService.getLevelDeptById(4);
		DeptLevelDto after = new DeptLevelDto();
		after.setId(4);
		after.setParentId(1);
		after.setLevel(LevelUtil.calculateLevel(parentDept.getLevel(), parentDept.getId()));
		List<Dept> childDeptList = deptService.getChildLevelDept();
		for (Dept  dept: childDeptList) {
			String beforeLevel = dept.getLevel();
			if(beforeLevel.indexOf(before.getLevel()) == 0) {
				String subLevel = beforeLevel.substring(before.getLevel().length());
				dept.setLevel(after.getLevel() + subLevel);
			}
		}
		Multimap<String, DeptLevelDto> levelDeptMap = ArrayListMultimap.create();
		List<DeptLevelDto> rootDeptList = new ArrayList<>();
		rootDeptList.add(after);
		DeptLevelDto deptDto = null;
		for (Dept dept : childDeptList) {
			deptDto = DeptLevelDto.adapt(dept);
			levelDeptMap.put(dept.getLevel(), deptDto);
		}
		deptService.listToTree(rootDeptList, levelDeptMap);
		System.out.println(new ObjectMapper().writeValueAsString(rootDeptList));
	}

	private List<Dept> getChildLevelDept() {
		List<Dept> deptList = new ArrayList<>();
		Dept dept = new Dept();
		dept.setId(5);
		dept.setParentId(4);
		dept.setSeq(0);
		dept.setName("level3.0");
		dept.setLevel(LevelUtil.calculateLevel("0.1.2", 4));
		deptList.add(dept);
		
		dept = new Dept();
		dept.setId(6);
		dept.setParentId(4);
		dept.setSeq(0);
		dept.setName("level3.1");
		dept.setLevel(LevelUtil.calculateLevel("0.1.2", 4));
		deptList.add(dept);
		return deptList;
	}

	private Dept getLevelDeptById(int i) {
		Dept dept = new Dept();
		dept.setId(4);
		dept.setParentId(2);
		dept.setSeq(0);
		dept.setName("level2.0");
		dept.setLevel(LevelUtil.calculateLevel("0.1", 2));
		return dept;
	}

	private static void getLevelDept(DeptService deptService) throws JsonProcessingException {
		List<Dept> deptList = deptService.getLevelDept();
		/**
		 * key是level,value是同一层次的部门对象集合
		 */
		Multimap<String, DeptLevelDto> levelDeptMap = ArrayListMultimap.create();
		
		List<DeptLevelDto> rootDeptList = new ArrayList<DeptLevelDto>();
		DeptLevelDto deptDto = null;
		
		for (Dept dept : deptList) {
			deptDto = DeptLevelDto.adapt(dept);
			levelDeptMap.put(dept.getLevel(), deptDto);
			if(deptDto.getLevel().equals(LevelUtil.ROOT)) {
				rootDeptList.add(deptDto);
			}
		}
		deptService.listToTree(rootDeptList, levelDeptMap);
		ObjectMapper objectMapper = new ObjectMapper();
		String deptTreeJson = objectMapper.writeValueAsString(rootDeptList);
		System.out.println(deptTreeJson);
	}
	/**
	 * 遍历同一层级的dept,从Multimap中拿到其下一集的dept并且放到deptDto的deptList中
	 * @param parentDeptList
	 * @param root
	 * @param levelDeptMap
	 */
	public void listToTree(List<DeptLevelDto> parentDeptList, Multimap<String, DeptLevelDto> levelDeptMap) {
		List<DeptLevelDto> deptLevelDtoList = null;
		if(CollectionUtils.isNotEmpty(parentDeptList)) {
			Collections.sort(parentDeptList, deptSeqComparator);
			//遍历同一层级的dept
			for (DeptLevelDto deptLevelDto : parentDeptList) {
				String parentLevel = deptLevelDto.getLevel();
				Integer parentId = deptLevelDto.getId();
				deptLevelDtoList = (List<DeptLevelDto>)levelDeptMap.get(LevelUtil.calculateLevel(parentLevel, parentId));
				deptLevelDto.setDeptList(deptLevelDtoList);
				listToTree(deptLevelDtoList, levelDeptMap);
			}
		}
	}
	
	public Comparator<DeptLevelDto> deptSeqComparator = new Comparator<DeptLevelDto>() {
		@Override
		public int compare(DeptLevelDto o1, DeptLevelDto o2) {
			return o1.getSeq() - o2.getSeq();
		}
	};
	
	private void testCountLevel() {
		String calculateLevel = LevelUtil.calculateLevel("1", 1);
		System.out.println(calculateLevel);
	}
	
	public List<Dept> getLevelDept() {
		List<Dept> deptList = new ArrayList<Dept>();
		Dept dept = new Dept();
		dept.setId(1);
		dept.setParentId(0);
		dept.setSeq(0);
		dept.setName("root");
		dept.setLevel(LevelUtil.ROOT);
		deptList.add(dept);
		
		dept = new Dept();
		dept.setId(2);
		dept.setParentId(1);
		dept.setSeq(0);
		dept.setName("level1.0");
		dept.setLevel(LevelUtil.calculateLevel("0", 1));
		deptList.add(dept);
		
		dept = new Dept();
		dept.setId(3);
		dept.setParentId(1);
		dept.setSeq(1);
		dept.setName("level1.1");
		dept.setLevel(LevelUtil.calculateLevel("0", 1));
		deptList.add(dept);
		
		dept = new Dept();
		dept.setId(4);
		dept.setParentId(2);
		dept.setSeq(0);
		dept.setName("level2.0");
		dept.setLevel(LevelUtil.calculateLevel("0.1", 2));
		deptList.add(dept);
		
		dept = new Dept();
		dept.setId(5);
		dept.setParentId(4);
		dept.setSeq(0);
		dept.setName("level3.0");
		dept.setLevel(LevelUtil.calculateLevel("0.1.2", 4));
		deptList.add(dept);
		
		dept = new Dept();
		dept.setId(6);
		dept.setParentId(4);
		dept.setSeq(0);
		dept.setName("level3.1");
		dept.setLevel(LevelUtil.calculateLevel("0.1.2", 4));
		deptList.add(dept);
		return deptList;
	}
}
源码 http://download.csdn.net/download/u014172271/10268699


   


 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值