list转tree和list中查找某节点下的所有数据操作
类的实例化顺序
父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、
父类非静态变量(父类实例成员变量)、父类构造函数、子类非静态变量(子类实例成员变量)、子类构造函数。
已知组织类Org{Stringid,Stringname,StringparentId},现在一List
publicstaticListchildList=newArrayList<>(); publicstaticList findChild(List list,Stringid){ for(Orgorg:list){ if(org.getParentId().equals(id)){ childList.add(org); findChild(list,org.getId());//递归实现 } } returnchildList; }
list转tree:
//node一开始为根节点 publicstaticTreeNodelistToTree(TreeNodenode,ListsourceLit){ //重根节点开始 for(TreeNodesourceNode:sourceLit){ if(sourceNode.getpId()==node.getId()){ if(node.getChildrenList()==null){ node.setChildrenList(newArrayList ()); } node.getChildrenList().add(listToTree(sourceNode,sourceLit)); } } returnnode; }
补充知识:Java实现树数据Tree与List互转并逐级汇总节点的值(支持树节点多列统计)
主要需求:a.实现树Tree与List互转b.Tree实现多列统计数据汇总。前度采用MiniUI。
逐级汇总数据:找到最小节点,然后回溯其所有父节点,注意值的重复计算问题。
构造一棵树的基本节点:
packagecom.example.demo.tree; importjava.util.ArrayList; importjava.util.List; /** *@ClassName:TreeNode *@Description:TODO(树的节点对象) *@author:pengjunlin *@motto:学习需要毅力,那就秀毅力 *@date2019-06-1823:35 */ publicclassTreeNode{ /** *节点ID */ privatelongid; /** *显示名称 */ privateStringlabel; /** *当前节点的唯一值 */ privatedoublevalue; /** *当前节点的多个值的表达方式 */ privatedouble[]multiValues=newdouble[]{}; /** *汇总单个节点的多个值 */ privateListvalues=newArrayList (); /** *当前节点所有子节点的值集合 */ privateList childrenMultiValues=newArrayList (); /** *父节点ID */ privatelongpid; /** *子节点集合对象 */ privateList children=newArrayList (); /** *是否计算本身 */ privatebooleanaddSelf=false; publiclonggetId(){ returnid; } publicvoidsetId(longid){ this.id=id; } publicStringgetLabel(){ returnlabel; } publicvoidsetLabel(Stringlabel){ this.label=label; } publicdoublegetValue(){ returnvalue; } publicvoidsetValue(doublevalue){ this.value=value; } publicdouble[]getMultiValues(){ returnmultiValues; } publicvoidsetMultiValues(double[]multiValues){ this.multiValues=multiValues; } publicList getValues(){ returnvalues; } publicvoidsetValues(List values){ this.values=values; } publicList getChildrenMultiValues(){ returnchildrenMultiValues; } publicvoidsetChildrenMultiValues(List childrenMultiValues){ this.childrenMultiValues=childrenMultiValues; } publiclonggetPid(){ returnpid; } publicvoidsetPid(longpid){ this.pid=pid; } publicList getChildren(){ returnchildren; } publicvoidsetChildren(List children){ this.children=children; } publicbooleanisAddSelf(){ returnaddSelf; } publicvoidsetAddSelf(booleanaddSelf){ this.addSelf=addSelf; } }
构造树管理工具:
packagecom.example.demo.tree; importjava.util.ArrayList; importjava.util.HashMap; importjava.util.List; importjava.util.Map; /** *@ClassName:TreeManager *@Description:TODO(树结构数据管理-实践验证) *@author:pengjunlin *@motto:学习需要毅力,那就秀毅力 *@date2019-06-1823:47 */ publicclassTreeManager{ /** *将List转成tree结构数据 *@paramlist *@paramrootId默认顶级节点ID *@return */ publicstaticListlistToTree(List list,longrootId){ List tree=newArrayList (); Map map=newHashMap (); //将所有的数据,以键值对的形式装入map中 for(TreeNodenode:list){ //去除冗余的子节点 node.setChildren(newArrayList ()); map.put(node.getId(),node); } for(TreeNodenode:list){ //如果id是父级的话就放入tree中 if(node.getId()==rootId){ tree.add(node); }else{ //子级通过父id获取到父级的类型 TreeNodeparent=map.get(node.getPid()); //父级获得子级,再将子级放到对应的父级中 if(parent!=null){ parent.getChildren().add(node); } } } returntree; } /** *将tree结构数据转成List结构 *@paramlist *@return */ publicstaticvoidtreeToList(TreeNodenode,List list){ if(list==null){ list=newArrayList (); } //设置当前节点的必要数据 TreeNodenodeValue=newTreeNode(); 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(newArrayList ()); list.add(nodeValue); //遍历递归子节点 if(node.getChildren().size()>0){ for(inti=0;i listToTreeWithSingleValue(List list,longrootId){ Map map=newHashMap (); //将所有的数据,以键值对的形式装入map中 for(TreeNodenode:list){ //去除冗余的子节点 node.setChildren(newArrayList ()); map.put(node.getId(),node); } List tree=listToTree(list,rootId); /*//存储最小子节点ID Map leafList=newHashMap (); findMinNodes(tree.get(0),leafList,0); //设置每个节点的值 for(Longid_:leafList.keySet()){ //内部递归树的父节点层级多于2会存在重复计算 setParentNodeValue(map,id_); }*/ //存储最小子节点ID Map leaf=newHashMap (); findMinNodes(tree.get(0),leaf); //逐级设置父节点的值 setValuesToParentNode(leaf,map); //汇总所有节点的值 doubletotal=0; for(TreeNodenode:map.values()){ total=0; for(doublevalue:node.getValues()){ total+=value; } node.setValue(total); map.put(node.getId(),node); } List result=newArrayList (); for(TreeNodenode:map.values()){ result.add(node); } returnlistToTree(result,rootId); } /** *转换数据格式并设置对应节点的值汇总到根节点 *@paramtree *@return */ publicstaticList treeToListWithSingleValue(TreeNodetree){ List list=newArrayList (); //获取到List treeToList(tree,list); Map map=newHashMap (); //将所有的数据,以键值对的形式装入map中 for(TreeNodenode:list){ //去除冗余的子节点 node.setChildren(newArrayList ()); map.put(node.getId(),node); } /*//存储最小子节点ID Map leafList=newHashMap (); findMinNodes(tree,leafList,0); //设置每个节点的值 for(Longid_:leafList.keySet()){ //内部递归树的父节点层级多于2会存在重复计算 setParentNodeValue(map,id_); }*/ //存储最小子节点ID Map leaf=newHashMap (); findMinNodes(tree,leaf); //逐级设置父节点的值 setValuesToParentNode(leaf,map); //汇总所有节点的值 doubletotal=0; for(TreeNodenode:map.values()){ total=0; for(doublevalue:node.getValues()){ total+=value; } node.setValue(total); map.put(node.getId(),node); } List result=newArrayList (); for(TreeNodenode:map.values()){ result.add(node); } returnresult; } /** *转换数据格式并设置对应节点的值汇总到根节点 *@paramlist *@paramrootId *@paramcolumns *@return */ publicstaticList listToTreeWithMultiValues(List list,longrootId,intcolumns){ Map map=newHashMap (); //将所有的数据,以键值对的形式装入map中 for(TreeNodenode:list){ //去除冗余的子节点 node.setChildren(newArrayList ()); map.put(node.getId(),node); } List tree=listToTree(list,rootId); /*//存储最小子节点ID Map leafList=newHashMap (); findMinNodes(tree.get(0),leafList,0); //设置每个节点的值 for(Longid_:leafList.keySet()){ //内部递归树的父节点层级多于2会存在重复计算 setParentNodeMultiValues(map,id_); }*/ //存储最小子节点ID Map leaf=newHashMap (); findMinNodes(tree.get(0),leaf); //逐级追加父节点的值 setMultiValuesToParentNode(leaf,map); //汇总所有节点的值 double[]valueColumns=null; for(TreeNodenode:map.values()){ valueColumns=newdouble[columns]; for(double[]values:node.getChildrenMultiValues()){ for(inti=0,j=values.length;i result=newArrayList (); for(TreeNodenode:map.values()){ result.add(node); } returnlistToTree(result,rootId); } /** *转换数据格式并设置对应节点的值汇总到根节点 *@paramtree *@paramcolumns *@return */ publicstaticList treeToListWithMultiValues(TreeNodetree,intcolumns){ List list=newArrayList (); //获取到List treeToList(tree,list); Map map=newHashMap (); //将所有的数据,以键值对的形式装入map中 for(TreeNodenode:list){ //去除冗余的子节点 node.setChildren(newArrayList ()); map.put(node.getId(),node); } /* //存储最小子节点ID Map leafList=newHashMap (); findMinNodes(tree,leafList,0); //设置每个节点的值 for(Longid_:leafList.keySet()){ //内部递归树的父节点层级多于2会存在重复计算 setParentNodeMultiValues(map,id_); }*/ //存储最小子节点ID Map leaf=newHashMap (); findMinNodes(tree,leaf); //逐级追加父节点的值 setMultiValuesToParentNode(leaf,map); //汇总所有节点的值 double[]valueColumns=null; for(TreeNodenode:map.values()){ valueColumns=newdouble[columns]; for(double[]values:node.getChildrenMultiValues()){ for(inti=0,j=values.length;i result=newArrayList (); for(TreeNodenode:map.values()){ result.add(node); } returnresult; } /** *逐级追加设置节点的值(单个值) *@paramleaf *@parammap */ publicstaticvoidsetValuesToParentNode(Map leaf,Map map){ Map newLeaf=newHashMap (); //设置每个节点的值 for(Longid_:leaf.keySet()){ setParentNodeValue(newLeaf,map,id_); } if(newLeaf.size()>1){ setValuesToParentNode(newLeaf,map); } } /** *逐级追加设置节点的值(多个值) *@paramleaf *@parammap */ publicstaticvoidsetMultiValuesToParentNode(Map leaf,Map map){ Map newLeaf=newHashMap (); //设置每个节点的值 for(Longid_:leaf.keySet()){ setParentNodeMultiValues(newLeaf,map,id_); } if(newLeaf.size()>1){ setMultiValuesToParentNode(newLeaf,map); } } /** *数学运算 *@parammathChar *@paramdest *@paramnewValue */ publicstaticvoidmathHandle(StringmathChar,doubledest,doublenewValue){ switch(mathChar){ case"+": dest+=newValue; break; case"-": dest-=newValue; break; case"*": dest*=newValue; break; case"/": dest/=newValue; break; default: break; } } /** *查找最小子叶节点(没有子节点的节点) *@paramnode *@paramleafList */ privatestaticvoidfindMinNodes(TreeNodenode,Map leafList){ if(node.getChildren().size()>0){ TreeNodenodeTmp=null; for(inti=0;i newLeaf,Map map,longid){ TreeNodenode=map.get(id); //设置自身节点的值 if(!node.isAddSelf()){ node.setAddSelf(true); node.getValues().add(node.getValue()); //更新节点数据 map.put(node.getId(),node); } TreeNodepNode=map.get(node.getPid()); if(pNode!=null){ //将子节点的值赋给父节点 pNode.getValues().addAll(node.getValues()); //设置自身节点的值 if(!pNode.isAddSelf()){ pNode.setAddSelf(true); pNode.getValues().add(pNode.getValue()); } //更新节点数据 map.put(pNode.getId(),pNode); //setParentNodeValue(map,pNode.getId()); newLeaf.put(pNode.getId(),pNode.getId()); } } /** *根据ID逐级查找父节点并设置值(设置多个值逐级递归) *@parammap *@paramid */ privatestaticvoidsetParentNodeMultiValues(Map newLeaf,Map map,longid){ TreeNodenode=map.get(id); //设置自身节点的值 if(!node.isAddSelf()){ node.setAddSelf(true); node.getChildrenMultiValues().add(node.getMultiValues()); //更新节点数据 map.put(node.getId(),node); } TreeNodepNode=map.get(node.getPid()); if(pNode!=null){ //将子节点的值赋给父节点 pNode.getChildrenMultiValues().addAll(node.getChildrenMultiValues()); //设置自身节点的值 if(!pNode.isAddSelf()){ pNode.setAddSelf(true); pNode.getChildrenMultiValues().add(pNode.getMultiValues()); } //更新节点数据 map.put(pNode.getId(),pNode); //setParentNodeMultiValues(map,pNode.getId()); newLeaf.put(pNode.getId(),pNode.getId()); } } @SuppressWarnings("unused") publicstaticvoidmain(String[]args){ TreeNodetree=newTreeNode(); tree.setId(1); tree.setLabel("顶层节点"); tree.setValue(1); tree.setChildrenMultiValues(newArrayList ()); tree.setPid(0); List list=newArrayList (); TreeNodenode1=newTreeNode(); node1.setId(2); node1.setLabel("子节点1"); node1.setValue(100); node1.setMultiValues(newdouble[]{5,7,3}); node1.setChildrenMultiValues(newArrayList ()); node1.setPid(1); list.add(node1); TreeNodenode2=newTreeNode(); node2.setId(3); node2.setLabel("子节点2"); node2.setValue(10); node2.setMultiValues(newdouble[]{2,5,8}); node2.setChildrenMultiValues(newArrayList ()); node2.setPid(1); list.add(node2); tree.setChildren(list); List destList=newArrayList (); TreeManager.treeToList(tree,destList); System.out.println("tree转list完成"); List treeList=TreeManager.listToTree(destList,1); System.out.println("List转tree完成"); /*******************注意单个值计算结果会影响多个值计算结果**************/ List treeListSingleValue=TreeManager.listToTreeWithSingleValue(destList,1); System.out.println("List转tree汇总唯一值value完成"); List treeListSingleValue2=TreeManager.treeToListWithSingleValue(tree); System.out.println("tree转List汇总唯一值value完成"); //List treeListMultiValues=TreeManager.listToTreeWithMultiValues(destList,1,3); //System.out.println("List转tree汇总多个值values完成"); // //List treeListMultiValues2=TreeManager.treeToListWithMultiValues(tree,3); //System.out.println("tree转List汇总多个值values完成"); } }
注:如果数据字段跟工具树的不一致可以使用Map转对象来实现。
Github源码:点击进入
以上这篇list转tree和list中查找某节点下的所有数据操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。