您好,登錄后才能下訂單哦!
類的實例化順序
父類靜態(tài)變量、 父類靜態(tài)代碼塊、 子類靜態(tài)變量、 子類靜態(tài)代碼塊、
父類非靜態(tài)變量(父類實例成員變量)、 父類構(gòu)造函數(shù)、 子類非靜態(tài)變量(子類實例成員變量)、 子類構(gòu)造函數(shù)。
已知組織類Org{String id,String name,String parentId},現(xiàn)在一List<Org>中存放無序的Org數(shù)據(jù),求一個組織id下的所有組織。
public static List<Org> childList=new ArrayList<>(); public static List<Org> findChild(List<Org> list,String id){ for (Org org:list){ if(org.getParentId().equals(id)){ childList.add(org); findChild(list,org.getId()); //遞歸實現(xiàn) } } return childList; }
list轉(zhuǎn)tree:
// node一開始為根節(jié)點 public static TreeNode listToTree(TreeNode node, List<TreeNode> sourceLit){ // 重根節(jié)點開始 for (TreeNode sourceNode : sourceLit){ if (sourceNode.getpId() == node.getId()){ if(node.getChildrenList() == null){ node.setChildrenList(new ArrayList<TreeNode>()); } node.getChildrenList().add(listToTree(sourceNode, sourceLit)); } } return node; }
補充知識:Java實現(xiàn)樹數(shù)據(jù)Tree與List互轉(zhuǎn)并逐級匯總節(jié)點的值(支持樹節(jié)點多列統(tǒng)計)
主要需求:a.實現(xiàn)樹Tree與List互轉(zhuǎn) b.Tree實現(xiàn)多列統(tǒng)計數(shù)據(jù)匯總。前度采用MiniUI。
逐級匯總數(shù)據(jù):找到最小節(jié)點,然后回溯其所有父節(jié)點,注意值的重復計算問題。
構(gòu)造一棵樹的基本節(jié)點:
package com.example.demo.tree; import java.util.ArrayList; import java.util.List; /** * @ClassName: TreeNode * @Description: TODO(樹的節(jié)點對象) * @author: pengjunlin * @motto: 學習需要毅力,那就秀毅力 * @date 2019-06-18 23:35 */ public class TreeNode { /** * 節(jié)點ID */ private long id; /** * 顯示名稱 */ private String label; /** * 當前節(jié)點的唯一值 */ private double value; /** * 當前節(jié)點的多個值的表達方式 */ private double[] multiValues=new double[]{}; /** * 匯總單個節(jié)點的多個值 */ private List<Double> values=new ArrayList<Double>(); /** * 當前節(jié)點所有子節(jié)點的值集合 */ private List<double []> childrenMultiValues=new ArrayList<double []>(); /** * 父節(jié)點ID */ private long pid; /** * 子節(jié)點集合對象 */ private List<TreeNode> children=new ArrayList<TreeNode>(); /** * 是否計算本身 */ private boolean addSelf=false; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public double getValue() { return value; } public void setValue(double value) { this.value = value; } public double[] getMultiValues() { return multiValues; } public void setMultiValues(double[] multiValues) { this.multiValues = multiValues; } public List<Double> getValues() { return values; } public void setValues(List<Double> values) { this.values = values; } public List<double[]> getChildrenMultiValues() { return childrenMultiValues; } public void setChildrenMultiValues(List<double[]> childrenMultiValues) { this.childrenMultiValues = childrenMultiValues; } public long getPid() { return pid; } public void setPid(long pid) { this.pid = pid; } public List<TreeNode> getChildren() { return children; } public void setChildren(List<TreeNode> children) { this.children = children; } public boolean isAddSelf() { return addSelf; } public void setAddSelf(boolean addSelf) { this.addSelf = addSelf; } }
構(gòu)造樹管理工具:
package com.example.demo.tree; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @ClassName: TreeManager * @Description: TODO(樹結(jié)構(gòu)數(shù)據(jù)管理-實踐驗證) * @author: pengjunlin * @motto: 學習需要毅力,那就秀毅力 * @date 2019-06-18 23:47 */ public class TreeManager { /** * 將List轉(zhuǎn)成tree結(jié)構(gòu)數(shù)據(jù) * @param list * @param rootId 默認頂級節(jié)點ID * @return */ public static List<TreeNode> listToTree(List<TreeNode> list,long rootId){ List<TreeNode> tree=new ArrayList<TreeNode>(); Map<Long, TreeNode> map = new HashMap<Long, TreeNode>(); // 將所有的數(shù)據(jù),以鍵值對的形式裝入map中 for (TreeNode node : list) { // 去除冗余的子節(jié)點 node.setChildren(new ArrayList<TreeNode>()); map.put(node.getId(), node); } for (TreeNode node : list) { // 如果id是父級的話就放入tree中 if (node.getId() == rootId) { tree.add(node); } else { // 子級通過父id獲取到父級的類型 TreeNode parent = map.get(node.getPid()); // 父級獲得子級,再將子級放到對應的父級中 if(parent!=null){ parent.getChildren().add(node); } } } return tree; } /** * 將tree結(jié)構(gòu)數(shù)據(jù)轉(zhuǎn)成List結(jié)構(gòu) * @param list * @return */ public static void treeToList(TreeNode node,List<TreeNode> list){ if(list==null){ list=new ArrayList<TreeNode>(); } //設置當前節(jié)點的必要數(shù)據(jù) TreeNode nodeValue=new TreeNode(); nodeValue.setId(node.getId()); nodeValue.setLabel(node.getLabel()); nodeValue.setValue(node.getValue()); nodeValue.setMultiValues(node.getMultiValues()); nodeValue.setChildrenMultiValues(node.getChildrenMultiValues()); nodeValue.setPid(node.getPid()); nodeValue.setChildren(new ArrayList<TreeNode>()); list.add(nodeValue); //遍歷遞歸子節(jié)點 if(node.getChildren().size()>0){ for (int i = 0; i < node.getChildren().size(); i++) { TreeNode node_= node.getChildren().get(i); treeToList(node_,list); } } } /** * 轉(zhuǎn)換數(shù)據(jù)格式并設置對應節(jié)點的值匯總到根節(jié)點 * @param list * @param rootId * @return */ public static List<TreeNode> listToTreeWithSingleValue(List<TreeNode> list,long rootId){ Map<Long, TreeNode> map = new HashMap<Long, TreeNode>(); // 將所有的數(shù)據(jù),以鍵值對的形式裝入map中 for (TreeNode node : list) { // 去除冗余的子節(jié)點 node.setChildren(new ArrayList<TreeNode>()); map.put(node.getId(), node); } List<TreeNode> tree=listToTree(list,rootId); /* // 存儲最小子節(jié)點ID Map<Long,Object> leafList=new HashMap<Long,Object>(); findMinNodes(tree.get(0),leafList,0); // 設置每個節(jié)點的值 for (Long id_: leafList.keySet()) { // 內(nèi)部遞歸樹的父節(jié)點層級多于2會存在重復計算 setParentNodeValue(map,id_); }*/ // 存儲最小子節(jié)點ID Map<Long,Object> leaf=new HashMap<Long,Object>(); findMinNodes(tree.get(0),leaf); // 逐級設置父節(jié)點的值 setValuesToParentNode(leaf, map); // 匯總所有節(jié)點的值 double total=0; for (TreeNode node:map.values() ) { total=0; for (double value: node.getValues() ) { total+=value; } node.setValue(total); map.put(node.getId(),node); } List<TreeNode> result=new ArrayList<TreeNode>(); for (TreeNode node:map.values()) { result.add(node); } return listToTree(result,rootId); } /** * 轉(zhuǎn)換數(shù)據(jù)格式并設置對應節(jié)點的值匯總到根節(jié)點 * @param tree * @return */ public static List<TreeNode> treeToListWithSingleValue(TreeNode tree){ List<TreeNode> list=new ArrayList<TreeNode>(); // 獲取到List treeToList(tree,list); Map<Long, TreeNode> map = new HashMap<Long, TreeNode>(); // 將所有的數(shù)據(jù),以鍵值對的形式裝入map中 for (TreeNode node : list) { // 去除冗余的子節(jié)點 node.setChildren(new ArrayList<TreeNode>()); map.put(node.getId(), node); } /* // 存儲最小子節(jié)點ID Map<Long,Object> leafList=new HashMap<Long,Object>(); findMinNodes(tree,leafList,0); // 設置每個節(jié)點的值 for (Long id_: leafList.keySet()) { // 內(nèi)部遞歸樹的父節(jié)點層級多于2會存在重復計算 setParentNodeValue(map,id_); }*/ // 存儲最小子節(jié)點ID Map<Long,Object> leaf=new HashMap<Long,Object>(); findMinNodes(tree,leaf); // 逐級設置父節(jié)點的值 setValuesToParentNode(leaf, map); // 匯總所有節(jié)點的值 double total=0; for (TreeNode node:map.values() ) { total=0; for (double value: node.getValues() ) { total+=value; } node.setValue(total); map.put(node.getId(),node); } List<TreeNode> result=new ArrayList<TreeNode>(); for (TreeNode node:map.values()) { result.add(node); } return result; } /** * 轉(zhuǎn)換數(shù)據(jù)格式并設置對應節(jié)點的值匯總到根節(jié)點 * @param list * @param rootId * @param columns * @return */ public static List<TreeNode> listToTreeWithMultiValues(List<TreeNode> list,long rootId,int columns){ Map<Long, TreeNode> map = new HashMap<Long, TreeNode>(); // 將所有的數(shù)據(jù),以鍵值對的形式裝入map中 for (TreeNode node : list) { // 去除冗余的子節(jié)點 node.setChildren(new ArrayList<TreeNode>()); map.put(node.getId(), node); } List<TreeNode> tree=listToTree(list,rootId); /* // 存儲最小子節(jié)點ID Map<Long,Object> leafList=new HashMap<Long,Object>(); findMinNodes(tree.get(0),leafList,0); // 設置每個節(jié)點的值 for (Long id_: leafList.keySet()) { // 內(nèi)部遞歸樹的父節(jié)點層級多于2會存在重復計算 setParentNodeMultiValues(map,id_); }*/ // 存儲最小子節(jié)點ID Map<Long,Object> leaf=new HashMap<Long,Object>(); findMinNodes(tree.get(0),leaf); // 逐級追加父節(jié)點的值 setMultiValuesToParentNode(leaf, map); // 匯總所有節(jié)點的值 double [] valueColumns=null; for (TreeNode node:map.values() ) { valueColumns=new double[columns]; for (double [] values: node.getChildrenMultiValues() ) { for (int i = 0,j=values.length; i < j; i++) { valueColumns[i]+=values[i]; } } node.setMultiValues(valueColumns); map.put(node.getId(),node); } List<TreeNode> result=new ArrayList<TreeNode>(); for (TreeNode node:map.values()) { result.add(node); } return listToTree(result,rootId); } /** * 轉(zhuǎn)換數(shù)據(jù)格式并設置對應節(jié)點的值匯總到根節(jié)點 * @param tree * @param columns * @return */ public static List<TreeNode> treeToListWithMultiValues(TreeNode tree,int columns){ List<TreeNode> list=new ArrayList<TreeNode>(); // 獲取到List treeToList(tree,list); Map<Long, TreeNode> map = new HashMap<Long, TreeNode>(); // 將所有的數(shù)據(jù),以鍵值對的形式裝入map中 for (TreeNode node : list) { // 去除冗余的子節(jié)點 node.setChildren(new ArrayList<TreeNode>()); map.put(node.getId(), node); } /* // 存儲最小子節(jié)點ID Map<Long,Object> leafList=new HashMap<Long,Object>(); findMinNodes(tree,leafList,0); // 設置每個節(jié)點的值 for (Long id_: leafList.keySet()) { // 內(nèi)部遞歸樹的父節(jié)點層級多于2會存在重復計算 setParentNodeMultiValues(map,id_); }*/ // 存儲最小子節(jié)點ID Map<Long,Object> leaf=new HashMap<Long,Object>(); findMinNodes(tree,leaf); // 逐級追加父節(jié)點的值 setMultiValuesToParentNode(leaf, map); // 匯總所有節(jié)點的值 double [] valueColumns=null; for (TreeNode node:map.values() ) { valueColumns=new double[columns]; for (double [] values: node.getChildrenMultiValues() ) { for (int i = 0,j=values.length; i < j; i++) { valueColumns[i]+=values[i]; } } node.setMultiValues(valueColumns); map.put(node.getId(),node); } List<TreeNode> result=new ArrayList<TreeNode>(); for (TreeNode node:map.values()) { result.add(node); } return result; } /** * 逐級追加設置節(jié)點的值(單個值) * @param leaf * @param map */ public static void setValuesToParentNode(Map<Long,Object> leaf,Map<Long, TreeNode> map){ Map<Long,Object> newLeaf=new HashMap<Long,Object>(); // 設置每個節(jié)點的值 for (Long id_: leaf.keySet()) { setParentNodeValue(newLeaf,map,id_); } if(newLeaf.size()>1){ setValuesToParentNode(newLeaf, map); } } /** * 逐級追加設置節(jié)點的值(多個值) * @param leaf * @param map */ public static void setMultiValuesToParentNode( Map<Long,Object> leaf,Map<Long, TreeNode> map){ Map<Long,Object> newLeaf=new HashMap<Long,Object>(); // 設置每個節(jié)點的值 for (Long id_: leaf.keySet()) { setParentNodeMultiValues(newLeaf,map,id_); } if(newLeaf.size()>1){ setMultiValuesToParentNode(newLeaf, map); } } /** * 數(shù)學運算 * @param mathChar * @param dest * @param newValue */ public static void mathHandle(String mathChar,double dest,double newValue){ switch (mathChar) { case "+": dest+=newValue; break; case "-": dest-=newValue; break; case "*": dest*=newValue; break; case "/": dest/=newValue; break; default: break; } } /** * 查找最小子葉節(jié)點(沒有子節(jié)點的節(jié)點) * @param node * @param leafList */ private static void findMinNodes(TreeNode node,Map<Long,Object> leafList){ if(node.getChildren().size()>0){ TreeNode nodeTmp=null; for (int i = 0; i < node.getChildren().size(); i++) { nodeTmp= node.getChildren().get(i); findMinNodes(nodeTmp,leafList); } }else{ leafList.put(node.getId(),node.getId()); } } /** * 根據(jù)ID逐級查找父節(jié)點并設置值(設置單個值逐級遞歸) * @param map * @param id */ private static void setParentNodeValue(Map<Long,Object> newLeaf,Map<Long, TreeNode> map,long id){ TreeNode node=map.get(id); // 設置自身節(jié)點的值 if(!node.isAddSelf()){ node.setAddSelf(true); node.getValues().add(node.getValue()); // 更新節(jié)點數(shù)據(jù) map.put(node.getId(),node); } TreeNode pNode=map.get(node.getPid()); if(pNode!=null){ // 將子節(jié)點的值賦給父節(jié)點 pNode.getValues().addAll(node.getValues()); // 設置自身節(jié)點的值 if(!pNode.isAddSelf()){ pNode.setAddSelf(true); pNode.getValues().add(pNode.getValue()); } // 更新節(jié)點數(shù)據(jù) map.put(pNode.getId(),pNode); //setParentNodeValue(map,pNode.getId()); newLeaf.put(pNode.getId(), pNode.getId()); } } /** * 根據(jù)ID逐級查找父節(jié)點并設置值(設置多個值逐級遞歸) * @param map * @param id */ private static void setParentNodeMultiValues(Map<Long,Object> newLeaf,Map<Long, TreeNode> map,long id){ TreeNode node=map.get(id); // 設置自身節(jié)點的值 if(!node.isAddSelf()){ node.setAddSelf(true); node.getChildrenMultiValues().add(node.getMultiValues()); // 更新節(jié)點數(shù)據(jù) map.put(node.getId(),node); } TreeNode pNode=map.get(node.getPid()); if(pNode!=null){ // 將子節(jié)點的值賦給父節(jié)點 pNode.getChildrenMultiValues().addAll(node.getChildrenMultiValues()); // 設置自身節(jié)點的值 if(!pNode.isAddSelf()){ pNode.setAddSelf(true); pNode.getChildrenMultiValues().add(pNode.getMultiValues()); } // 更新節(jié)點數(shù)據(jù) map.put(pNode.getId(),pNode); //setParentNodeMultiValues(map,pNode.getId()); newLeaf.put(pNode.getId(), pNode.getId()); } } @SuppressWarnings("unused") public static void main(String[] args) { TreeNode tree=new TreeNode(); tree.setId(1); tree.setLabel("頂層節(jié)點"); tree.setValue(1); tree.setChildrenMultiValues(new ArrayList<double []>()); tree.setPid(0); List<TreeNode> list =new ArrayList<TreeNode>(); TreeNode node1=new TreeNode(); node1.setId(2); node1.setLabel("子節(jié)點1"); node1.setValue(100); node1.setMultiValues(new double[]{5,7,3}); node1.setChildrenMultiValues(new ArrayList<double []>()); node1.setPid(1); list.add(node1); TreeNode node2=new TreeNode(); node2.setId(3); node2.setLabel("子節(jié)點2"); node2.setValue(10); node2.setMultiValues(new double[]{2,5,8}); node2.setChildrenMultiValues(new ArrayList<double []>()); node2.setPid(1); list.add(node2); tree.setChildren(list); List<TreeNode> destList=new ArrayList<TreeNode>(); TreeManager.treeToList(tree,destList); System.out.println("tree轉(zhuǎn)list完成"); List<TreeNode> treeList=TreeManager.listToTree(destList,1); System.out.println("List轉(zhuǎn)tree完成"); /*******************注意單個值計算結(jié)果會影響多個值計算結(jié)果**************/ List<TreeNode> treeListSingleValue=TreeManager.listToTreeWithSingleValue(destList,1); System.out.println("List轉(zhuǎn)tree 匯總唯一值value完成"); List<TreeNode> treeListSingleValue2=TreeManager.treeToListWithSingleValue(tree); System.out.println("tree轉(zhuǎn)List 匯總唯一值value完成"); // List<TreeNode> treeListMultiValues=TreeManager.listToTreeWithMultiValues(destList,1,3); // System.out.println("List轉(zhuǎn)tree 匯總多個值values完成"); // // List<TreeNode> treeListMultiValues2=TreeManager.treeToListWithMultiValues(tree,3); // System.out.println("tree轉(zhuǎn)List 匯總多個值values完成"); } }
注:如果數(shù)據(jù)字段跟工具樹的不一致可以使用Map轉(zhuǎn)對象來實現(xiàn)。
Github源碼:點擊進入
以上這篇list轉(zhuǎn)tree和list中查找某節(jié)點下的所有數(shù)據(jù)操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持億速云。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。