业务分析
实现理论上无限层级的组织部门机构,例如理事会->经理部门->销售部->外宣部->我;
实现方法
使用List
知道最多几层机构的情况下,foreach不断排序列出,代码示例如下
public List<menu> listAllForRole() {
List<SystemMenuEntity> systemRoleMenuEntities = getStatic();
if (systemRoleMenuEntities.size()>0){
//获取一级菜单
for (SystemMenuEntity entity:systemRoleMenuEntities) {
if (StringUtils.isBlank(entity.getParentId())) {
menu vo = new menu();
vo.setId(entity.getId());
vo.setName(entity.getUrl());
vo.setTitle(entity.getName());
vos.add(vo);
}
}
for (menu vo : vos) {
List<menu> chrildren = new ArrayList<>();
for (SystemMenuEntity systemRoleMenuEntity : systemRoleMenuEntities) {
//二级菜单
if (vo.getId().equals(systemRoleMenuEntity.getParentId())) {
menu menu = new menu();
menu.setId(systemRoleMenuEntity.getId());
menu.setName(systemRoleMenuEntity.getUrl());
menu.setTitle(systemRoleMenuEntity.getName());
List<menu> grandChrildren = new ArrayList<>();
for (SystemMenuEntity roleMenuEntity : systemRoleMenuEntities) {
//三级菜单
if (menu.getId().equals(roleMenuEntity.getParentId())) {
menu menuVO = new menu();
menuVO.setId(roleMenuEntity.getId());
menuVO.setName(roleMenuEntity.getUrl());
menuVO.setTitle(roleMenuEntity.getName());
List<menu> buttonMenus = new ArrayList<>();
for (SystemMenuEntity buttonMenuEntity : systemRoleMenuEntities) {
//四级按钮
if (menuVO.getId().equals(buttonMenuEntity.getParentId())) {
menu buttonmenuVO = new menu();
buttonmenuVO.setId(buttonMenuEntity.getId());
buttonmenuVO.setName(buttonMenuEntity.getUrl());
buttonmenuVO.setTitle(buttonMenuEntity.getName());
buttonMenus.add(buttonmenuVO);
}
}
menuVO.setButton(buttonMenus);
grandChrildren.add(menuVO);
}
}
menu.setChildren(grandChrildren);
chrildren.add(menu);
}
}
vo.setChildren(chrildren);
}
}
//}
return vos;
使用Map
使用map加桶排序,进行递归查询
public List<Object>listAllForRoleBetter(List<String> ids,int i) {
List<SystemMenuVO> vos = new ArrayList<>();
List<Object> mapVos = new ArrayList<>();
List<String> sortProperties = new ArrayList<>();
List<SystemMenuEntity> entities = getStatic();
for (SystemMenuEntity entity:entities) {
Map<String,Object> menuMap = new LinkedHashMap<>();
if (StringUtils.isBlank(entity.getParentId())){
menuMap.put("id",entity.getId());
menuMap.put("name",entity.getUrl());
menuMap.put("title",entity.getName());
menuMap.put("access",0);
menuMap.put("tChildren",menuChild(entity.getId(),entities,ids));
mapVos.add(menuMap);
}
}
return mapVos;
}
private List<?> menuChild(String id, List<SystemMenuEntity> entities,List<String> ids) {
List<Object> child = new ArrayList<>();
for (SystemMenuEntity entity:entities) {
Map<String,Object> menuMap = new LinkedHashMap<>();
if (id.equals(entity.getParentId())){
menuMap.put("id",entity.getId());
menuMap.put("name",entity.getUrl());
menuMap.put("title",entity.getName());
menuMap.put("access",0);
menuMap.put("tChildren",menuChild(entity.getId(),entities,ids));
child.add(menuMap);
}
}
return child;
}
使用Tree
两次循环完成树状结构
public List<SystemMenuVO> listAllForRoleMast(List<String> ids,int i) {
List<String> sortProperties = new ArrayList<>();
List<SystemMenuEntity> dataList = getStatic();
Map<String,SystemMenuVO> nodeList = new HashMap();
List<SystemMenuVO> vos = new ArrayList<>();
for (SystemMenuEntity dataRecord: dataList) {
List<SystemMenuVO> temp = new ArrayList<>();
SystemMenuVO node = new SystemMenuVO();
node.setId(dataRecord.getId());
node.setName(dataRecord.getUrl());
node.setTitle(dataRecord.getName());
node.setSystemMenuVOS(temp);
node.setAccess(0);
node.setParentId(StringUtils.isBlank(dataRecord.getParentId())?"":dataRecord.getParentId());
nodeList.put(node.getId(),node);
}
for (SystemMenuEntity dataRecord: dataList) {
SystemMenuVO vo = (SystemMenuVO)nodeList.get(dataRecord.getId());
if (StringUtils.isBlank(dataRecord.getParentId())){
vos.add(vo);
}else{
((SystemMenuVO)nodeList.get(dataRecord.getParentId())).getSystemMenuVOS().add(vo);
}
}
return vos;
}
生成静态数据
public List<SystemMenuEntity> getStatic(){
List<SystemMenuEntity> vo = new ArrayList<>();
//一级父类
for (int i = 0; i <5 ; i++) {
List<SystemMenuEntity> temp = new ArrayList<>();
SystemMenuEntity node = new SystemMenuEntity();
node.setId(UUID.randomUUID().toString());
node.setName("test"+i);
node.setUrl("test"+i);
node.setParentId(null);
vo.add(node);
for (int j = 0; j <5 ; j++) {
SystemMenuEntity node1 = new SystemMenuEntity();
node1.setId(UUID.randomUUID().toString());
node1.setName("1test"+j);
node.setUrl("test"+i);
node1.setParentId(node.getId());
vo.add(node1);
for (int k = 0; k <5 ; k++) {
SystemMenuEntity node2 = new SystemMenuEntity();
node2.setId(UUID.randomUUID().toString());
node2.setName("2test"+1);
node.setUrl("test"+i);
node2.setParentId(node1.getId());
vo.add(node2);
for (int m = 0; m <5 ; m++) {
SystemMenuEntity node3 = new SystemMenuEntity();
node3.setId(UUID.randomUUID().toString());
node3.setName("3test"+1);
node.setUrl("test"+i);
node3.setParentId(node2.getId());
vo.add(node3);
}
}
}
}
return vo;
}
测试方法
public void testTree(){
long begin;
long end;
begin = System.currentTimeMillis();
List<Object> map4 = sysMenuService.listAllForRoleBetter(null, 0);
end = System.currentTimeMillis();
System.out.println(end-begin);
System.out.println(JSON.toJSONString(map4));
begin = System.currentTimeMillis();
List<SystemMenuVO> map3 = sysMenuService.listAllForRoleMast(null, 0);
end = System.currentTimeMillis();
System.out.println(end-begin);
System.out.println(JSON.toJSONString(map3));
begin = System.currentTimeMillis();
List<SystemMenuVO> map1 = sysMenuService.listAllForRole(null, 0);
end = System.currentTimeMillis();
System.out.println(end-begin);
System.out.println(JSON.toJSONString(map1));
}
测试结果
方法 | ms | ms | ms |
---|---|---|---|
list | 44 | 27 | 20 |
map | 64 | 55 | 33 |
tree | 2 | 2 | 3 |
结论
做如这样的排序的时候,需要考虑两个,你从数据库拿出来的结构是怎么样的,有规律的数据排序会更加快速;第二你的结构是否经常变化,如果不是那么经常进行增删操作,可以做到缓存里面,使用redis。业务总是变化的,如果你对前端一无所知你就得问清楚前台需要数据以及格式。对于无限层级数据操作,使用桶排序的思路,可以构建出属于你自己的二叉树结构。这种做法让我想起了,java中方法参数的引用,是值传递?还是引用传递?对于对象是引用的传递。最后欢迎大家指教交流!