Java-无限层级菜单结构

业务分析

实现理论上无限层级的组织部门机构,例如理事会->经理部门->销售部->外宣部->我;

实现方法

使用List

知道最多几层机构的情况下,foreach不断排序列出,代码示例如下

public List 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 vos = new ArrayList<>();
        List<Object> mapVos = new ArrayList<>();
        List<String> sortProperties = new ArrayList<>();
        List 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 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 listAllForRoleMast(List ids,int i) {
        List sortProperties = new ArrayList<>();

        List dataList = getStatic();
        Map nodeList = new HashMap();
        List vos = new ArrayList<>();
        for (SystemMenuEntity dataRecord: dataList) {
            List 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 map4 = sysMenuService.listAllForRoleBetter(null, 0);
        end = System.currentTimeMillis();
        System.out.println(end-begin);
        System.out.println(JSON.toJSONString(map4));

        begin = System.currentTimeMillis();
        List map3 = sysMenuService.listAllForRoleMast(null, 0);
        end = System.currentTimeMillis();
        System.out.println(end-begin);
        System.out.println(JSON.toJSONString(map3));

        begin = System.currentTimeMillis();
        List 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中方法参数的引用,是值传递?还是引用传递?对于对象是引用的传递。最后欢迎大家指教交流!

你可能感兴趣的:(java)