將List數據轉成樹的兩種方式(遞歸、循環)


在做用戶菜單權限的時候(因為多張表關聯外鍵,hibernate返回回去會出現無限循環),所以把他轉換成和數據庫無關的VO類即可

一 、VO類如下

**
 *
 *
 * 封裝菜單的樹形結構
 * @author 六松島福小林
 *
 **/
public class MenuTree implements java.io.Serializable  {
    /**
     * 樹形節點id
     */
    private String id;

    /**
     * 菜單級別 0為第一級菜單,1為第二級菜單……
     */
    private  String  level;
    /**
     * 父級樹形id
     */
    private String parentId;

    /**
     * 樹形節點名稱
     */
    private String name;

    /**
     * 對應的菜單圖片路徑
     */

    private  String imagePath;

    /**
     * 菜單對應的url地址
     */
    private String url;

    /**
     * 子節點list
     */
    private List<MenuTree> children;

	……對應的Getter和Setter 這個在此省略……

}

二、封裝的樹形工具類如下
備注:循環和遞歸使用任何一種即可

  /**
     * 兩層循環實現建樹
     * @param menuTrees 傳入的樹節點列表
     * @return List<MenuTree> 子節點集合
     */
    public static List<MenuTree> build(List<MenuTree> menuTrees) {
            //返回的樹形結構數據
        List<MenuTree> trees = new ArrayList<>();
        //循環菜單樹形數據
        for (MenuTree menuTree : menuTrees) {
            //菜單級別為0,則是一級數據,根據實際情況判斷可修改相關關聯判斷
            if("0".equals(menuTree.getLevel())){
                trees.add(menuTree);
                for (MenuTree it : menuTrees) {
                    //找出一級菜單下面的所有二級菜單,並加入到list中去
                    if (menuTree.getId().equals(it.getParentId())) {
                        if (menuTree.getChildren() == null) {
                            menuTree.setChildren(new ArrayList<MenuTree>());
                        }
                        menuTree.getChildren().add(it);
                    }
                }
            }
        }
        return trees;
    }

    /**
     * 使用遞歸方法建樹
     * @param menuTrees  子節點集合
     * @return List<MenuTree>
     */
    public static List<MenuTree> buildByRecursive(List<MenuTree> menuTrees) {
        List<MenuTree> trees = new ArrayList<>();
        for (MenuTree menuTree : menuTrees) {
           //菜單級別為0,則是一級數據,根據實際情況判斷可修改相關關聯判斷
            if ("0".equals(menuTree.getLevel())) {
                trees.add(findChildren(menuTree,menuTrees));
            }
        }
        return trees;
    }

    /**
     * 遞歸查找子節點
     * @param menuTree  菜單數對象
     * @param menuTrees  子節點
     * @return MenuTree
     */
    private static MenuTree findChildren(MenuTree menuTree,List<MenuTree> menuTrees) {
        for (MenuTree it : menuTrees) {
            if(menuTree.getId().equals(it.getParentId())) {
                if (menuTree.getChildren() == null) {
                    menuTree.setChildren(new ArrayList<MenuTree>());
                }
                menuTree.getChildren().add(findChildren(it,menuTrees));
            }
        }
        return menuTree;
    }

三、調用


    /** *根據用戶id返回菜單的樹形數據 * @param userId 用戶的id * @param systemService 操作數據庫的service * @return 封裝好的菜單樹形數據 */
    public  static List<MenuTree> getMenuTreeList(String userId, SystemService systemService) throws Exception{
            //查詢該用戶所有的菜單數據
            List<Map<String, Object>> menuDataList = getMenuDataList(userId, systemService);
            //封裝成菜單對象list
            List<MenuTree> menuList = getMenuList(menuDataList);
            //調用封裝樹形數據方法
            return TreeBuilder.build(menuList);

    }

仍在不斷學習中,如有不妥還望各位大神留言指教

代碼下載地址 在下一篇根據用戶查詢相關菜單的博客中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM