溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

list轉(zhuǎn)tree和list中查找某節(jié)點下的所有數(shù)據(jù)操作

發(fā)布時間:2020-10-07 17:13:32 來源:腳本之家 閱讀:183 作者:風起塵落 欄目:開發(fā)技術

類的實例化順序

父類靜態(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é)點,注意值的重復計算問題。

list轉(zhuǎn)tree和list中查找某節(jié)點下的所有數(shù)據(jù)操作

list轉(zhuǎn)tree和list中查找某節(jié)點下的所有數(shù)據(jù)操作

構(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)容了,希望能給大家一個參考,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI