一些前端框架提供的樹形表格需要手動構建樹形列表(帶children屬性的對象數組),這種結構一般是需要在Java后台構建好。
構建的方式是通過id字段與父id字段做關聯,通過遞歸構建children字段來達到構建樹形列表的目的。
/** * 樹形表格工具類 * * @author yanggb */ public class TreeTableUtil {/** * 把列表轉換為樹結構 * * @param originalList 原始list數據 * @param idFieldName 作為唯一標示的字段名稱 * @param pidFieldName 父節點標識字段名 * @param childrenFieldName 子節點(列表)標識字段名 * @return 樹結構列表 */ public static <T> List<T> list2TreeList(List<T> originalList, String idFieldName, String pidFieldName, String childrenFieldName) { // 獲取根節點,即找出父節點為空的對象 List<T> rootNodeList = new ArrayList<>(); for (T t : originalList) { String parentId = null; try { parentId = BeanUtils.getProperty(t, pidFieldName); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { e.printStackTrace(); } if (StringUtils.isBlank(parentId)) { rootNodeList.add(0, t); } } // 將根節點從原始list移除,減少下次處理數據 originalList.removeAll(rootNodeList); // 遞歸封裝樹 try { packTree(rootNodeList, originalList, idFieldName, pidFieldName, childrenFieldName); } catch (Exception e) { e.printStackTrace(); } return rootNodeList; } /** * 封裝樹(向下遞歸) * * @param parentNodeList 要封裝為樹的父節點對象集合 * @param originalList 原始list數據 * @param keyName 作為唯一標示的字段名稱 * @param pidFieldName 父節點標識字段名 * @param childrenFieldName 子節點(列表)標識字段名 */ private static <T> void packTree(List<T> parentNodeList, List<T> originalList, String keyName, String pidFieldName, String childrenFieldName) throws Exception { for (T parentNode : parentNodeList) { // 找到當前父節點的子節點列表 List<T> children = packChildren(parentNode, originalList, keyName, pidFieldName, childrenFieldName); if (children.isEmpty()) { continue; } // 將當前父節點的子節點從原始list移除,減少下次處理數據 originalList.removeAll(children); // 開始下次遞歸 packTree(children, originalList, keyName, pidFieldName, childrenFieldName); } } /** * 封裝子對象 * * @param parentNode 父節點對象 * @param originalList 原始list數據 * @param keyName 作為唯一標示的字段名稱 * @param pidFieldName 父節點標識字段名 * @param childrenFieldName 子節點(列表)標識字段名 */ private static <T> List<T> packChildren(T parentNode, List<T> originalList, String keyName, String pidFieldName, String childrenFieldName) throws Exception { // 找到當前父節點下的子節點列表 List<T> childNodeList = new ArrayList<>(); String parentId = BeanUtils.getProperty(parentNode, keyName); for (T t : originalList) { String childNodeParentId = BeanUtils.getProperty(t, pidFieldName); if (parentId.equals(childNodeParentId)) { childNodeList.add(t); } } // 將當前父節點下的子節點列表寫入到當前父節點下(給子節點列表字段賦值) if (!childNodeList.isEmpty()) { FieldUtils.writeDeclaredField(parentNode, childrenFieldName, childNodeList, true); } return childNodeList; } }
直接上代碼就好了,我相信禿頭的你一定能看得懂。
"這個世界並不在乎你的自尊,只在乎你做出來的成績,然后再去強調你的感受。"