list转tree和list中查找某节点下的所有数据操作

类的实例化顺序

父类静态变量、 父类静态代码块、 子类静态变量、 子类静态代码块、

父类非静态变量(父类实例成员变量)、 父类构造函数、 子类非静态变量(子类实例成员变量)、 子类构造函数。

已知组织类Org{String id,String name,String parentId},现在一List<Org>中存放无序的Org数据,求一个组织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()); //递归实现

    }
  }
  return childList;
  }

list转tree:

 // node一开始为根节点
 public static TreeNode listToTree(TreeNode node, List<TreeNode> sourceLit){
  // 重根节点开始
  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实现树数据Tree与List互转并逐级汇总节点的值(支持树节点多列统计)

主要需求:a.实现树Tree与List互转 b.Tree实现多列统计数据汇总。前度采用MiniUI。

逐级汇总数据:找到最小节点,然后回溯其所有父节点,注意值的重复计算问题。

构造一棵树的基本节点:

package com.example.demo.tree;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: TreeNode
 * @Description: TODO(树的节点对象)
 * @author: pengjunlin
 * @motto: 学习需要毅力,那就秀毅力
 * @date 2019-06-18 23:35
 */
public class TreeNode {

 /**
  * 节点ID
  */
 private long id;
 /**
  * 显示名称
  */
 private String label;
 /**
  * 当前节点的唯一值
  */
 private double value;
 /**
  * 当前节点的多个值的表达方式
  */
 private double[] multiValues=new double[]{};
 /**
  * 汇总单个节点的多个值
  */
 private List<Double> values=new ArrayList<Double>();
 /**
  * 当前节点所有子节点的值集合
  */
 private List<double []> childrenMultiValues=new ArrayList<double []>();
 /**
  * 父节点ID
  */
 private long pid;
 /**
  * 子节点集合对象
  */
 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;
 }
}

构造树管理工具:

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(树结构数据管理-实践验证)
 * @author: pengjunlin
 * @motto: 学习需要毅力,那就秀毅力
 * @date 2019-06-18 23:47
 */
public class TreeManager {

 /**
  * 将List转成tree结构数据
  * @param list
  * @param rootId 默认顶级节点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>();
  // 将所有的数据,以键值对的形式装入map中
  for (TreeNode node : list) {
   // 去除冗余的子节点
   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结构数据转成List结构
  * @param list
  * @return
  */
 public static void treeToList(TreeNode node,List<TreeNode> list){
  if(list==null){
   list=new ArrayList<TreeNode>();
  }
  //设置当前节点的必要数据
  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);
  //遍历递归子节点
  if(node.getChildren().size()>0){
   for (int i = 0; i < node.getChildren().size(); i++) {
    TreeNode node_= node.getChildren().get(i);
    treeToList(node_,list);
   }
  }
 }

 /**
  * 转换数据格式并设置对应节点的值汇总到根节点
  * @param list
  * @param rootId
  * @return
  */
 public static List<TreeNode> listToTreeWithSingleValue(List<TreeNode> list,long rootId){
  Map<Long, TreeNode> map = new HashMap<Long, TreeNode>();
  // 将所有的数据,以键值对的形式装入map中
  for (TreeNode node : list) {
   // 去除冗余的子节点
   node.setChildren(new ArrayList<TreeNode>());
   map.put(node.getId(), node);
  }
  List<TreeNode> tree=listToTree(list,rootId);
  /* // 存储最小子节点ID
  Map<Long,Object> leafList=new HashMap<Long,Object>();
  findMinNodes(tree.get(0),leafList,0);
  // 设置每个节点的值
  for (Long id_: leafList.keySet()) {
   // 内部递归树的父节点层级多于2会存在重复计算
   setParentNodeValue(map,id_);
  }*/

  // 存储最小子节点ID
  Map<Long,Object> leaf=new HashMap<Long,Object>();
  findMinNodes(tree.get(0),leaf);
  // 逐级设置父节点的值
  setValuesToParentNode(leaf, map);

  // 汇总所有节点的值
  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);
 }

 /**
  * 转换数据格式并设置对应节点的值汇总到根节点
  * @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>();
  // 将所有的数据,以键值对的形式装入map中
  for (TreeNode node : list) {
   // 去除冗余的子节点
   node.setChildren(new ArrayList<TreeNode>());
   map.put(node.getId(), node);
  }
  /* // 存储最小子节点ID
  Map<Long,Object> leafList=new HashMap<Long,Object>();
  findMinNodes(tree,leafList,0);
  // 设置每个节点的值
  for (Long id_: leafList.keySet()) {
   // 内部递归树的父节点层级多于2会存在重复计算
   setParentNodeValue(map,id_);
  }*/

  // 存储最小子节点ID
  Map<Long,Object> leaf=new HashMap<Long,Object>();
  findMinNodes(tree,leaf);
  // 逐级设置父节点的值
  setValuesToParentNode(leaf, map);

  // 汇总所有节点的值
  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;
 }

 /**
  * 转换数据格式并设置对应节点的值汇总到根节点
  * @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>();
  // 将所有的数据,以键值对的形式装入map中
  for (TreeNode node : list) {
   // 去除冗余的子节点
   node.setChildren(new ArrayList<TreeNode>());
   map.put(node.getId(), node);
  }
  List<TreeNode> tree=listToTree(list,rootId);

  /* // 存储最小子节点ID
  Map<Long,Object> leafList=new HashMap<Long,Object>();
  findMinNodes(tree.get(0),leafList,0);
  // 设置每个节点的值
  for (Long id_: leafList.keySet()) {
   // 内部递归树的父节点层级多于2会存在重复计算
   setParentNodeMultiValues(map,id_);
  }*/

  // 存储最小子节点ID
  Map<Long,Object> leaf=new HashMap<Long,Object>();
  findMinNodes(tree.get(0),leaf);
  // 逐级追加父节点的值
  setMultiValuesToParentNode(leaf, map);

  // 汇总所有节点的值
  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);
 }

 /**
  * 转换数据格式并设置对应节点的值汇总到根节点
  * @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>();
  // 将所有的数据,以键值对的形式装入map中
  for (TreeNode node : list) {
   // 去除冗余的子节点
   node.setChildren(new ArrayList<TreeNode>());
   map.put(node.getId(), node);
  }
  /*
  // 存储最小子节点ID
  Map<Long,Object> leafList=new HashMap<Long,Object>();
  findMinNodes(tree,leafList,0);
  // 设置每个节点的值
  for (Long id_: leafList.keySet()) {
    // 内部递归树的父节点层级多于2会存在重复计算
   setParentNodeMultiValues(map,id_);
  }*/

  // 存储最小子节点ID
  Map<Long,Object> leaf=new HashMap<Long,Object>();
  findMinNodes(tree,leaf);
  // 逐级追加父节点的值
  setMultiValuesToParentNode(leaf, map);

  // 汇总所有节点的值
  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;
 }

 /**
  * 逐级追加设置节点的值(单个值)
  * @param leaf
  * @param map
  */
 public static void setValuesToParentNode(Map<Long,Object> leaf,Map<Long, TreeNode> map){
  Map<Long,Object> newLeaf=new HashMap<Long,Object>();
  // 设置每个节点的值
  for (Long id_: leaf.keySet()) {
   setParentNodeValue(newLeaf,map,id_);
  }
  if(newLeaf.size()>1){
   setValuesToParentNode(newLeaf, map);
  }
 }

 /**
  * 逐级追加设置节点的值(多个值)
  * @param leaf
  * @param map
  */
 public static void setMultiValuesToParentNode( Map<Long,Object> leaf,Map<Long, TreeNode> map){
  Map<Long,Object> newLeaf=new HashMap<Long,Object>();
  // 设置每个节点的值
  for (Long id_: leaf.keySet()) {
   setParentNodeMultiValues(newLeaf,map,id_);
  }
  if(newLeaf.size()>1){
   setMultiValuesToParentNode(newLeaf, map);
  }
 }

 /**
  * 数学运算
  * @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;
  }
 }

 /**
  * 查找最小子叶节点(没有子节点的节点)
  * @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());
  }
 }

 /**
  * 根据ID逐级查找父节点并设置值(设置单个值逐级递归)
  * @param map
  * @param id
  */
 private static void setParentNodeValue(Map<Long,Object> newLeaf,Map<Long, TreeNode> map,long id){
  TreeNode node=map.get(id);
  // 设置自身节点的值
  if(!node.isAddSelf()){
   node.setAddSelf(true);
   node.getValues().add(node.getValue());
   // 更新节点数据
   map.put(node.getId(),node);
  }
  TreeNode pNode=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逐级查找父节点并设置值(设置多个值逐级递归)
  * @param map
  * @param id
  */
 private static void setParentNodeMultiValues(Map<Long,Object> newLeaf,Map<Long, TreeNode> map,long id){
  TreeNode node=map.get(id);
  // 设置自身节点的值
  if(!node.isAddSelf()){
   node.setAddSelf(true);
   node.getChildrenMultiValues().add(node.getMultiValues());
   // 更新节点数据
   map.put(node.getId(),node);
  }
  TreeNode pNode=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")
 public static void main(String[] args) {
  TreeNode tree=new TreeNode();
  tree.setId(1);
  tree.setLabel("顶层节点");
  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("子节点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("子节点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转list完成");

  List<TreeNode> treeList=TreeManager.listToTree(destList,1);

  System.out.println("List转tree完成");

  /*******************注意单个值计算结果会影响多个值计算结果**************/

  List<TreeNode> treeListSingleValue=TreeManager.listToTreeWithSingleValue(destList,1);
  System.out.println("List转tree 汇总唯一值value完成");

  List<TreeNode> treeListSingleValue2=TreeManager.treeToListWithSingleValue(tree);
  System.out.println("tree转List 汇总唯一值value完成");

//  List<TreeNode> treeListMultiValues=TreeManager.listToTreeWithMultiValues(destList,1,3);
//  System.out.println("List转tree 汇总多个值values完成");
//
//  List<TreeNode> treeListMultiValues2=TreeManager.treeToListWithMultiValues(tree,3);
//  System.out.println("tree转List 汇总多个值values完成");

 }
}

注:如果数据字段跟工具树的不一致可以使用Map转对象来实现。

Github源码:点击进入

以上这篇list转tree和list中查找某节点下的所有数据操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java8 Stream对两个 List 遍历匹配数据的优化处理操作

    使用场景,有两个List<Map<String,Object>>集合,第一个集合的所有元素都是需要保留的. 第一个集合的值为: {name=张三丰1, id=1} {name=张三丰2, id=2} {name=张三丰3, id=3} {name=张三丰4, id=4} {name=张三丰5, id=5} {name=张三丰6, id=6} {name=张三丰7, id=7} {name=张三丰8, id=8} 第二个集合的值为: {grade=61, id=1} {grade=6

  • java8从list集合中取出某一属性的值的集合案例

    我就废话不多说了,大家还是直接看代码吧~ List<Order> list = new ArrayList<User>(); Order o1 = new Order("1","MCS-2019-1123"); list.add(o1 ); Order o2= new Order("2","MCS-2019-1124"); list.add(o2); Order o3= new Order("

  • list转tree和list中查找某节点下的所有数据操作

    类的实例化顺序 父类静态变量. 父类静态代码块. 子类静态变量. 子类静态代码块. 父类非静态变量(父类实例成员变量). 父类构造函数. 子类非静态变量(子类实例成员变量). 子类构造函数. 已知组织类Org{String id,String name,String parentId},现在一List<Org>中存放无序的Org数据,求一个组织id下的所有组织. public static List<Org> childList=new ArrayList<>(); p

  • Java Tree结构数据中查找匹配节点方式

    我就废话不多说了,大家还是直接看代码吧~ private boolean contains(List<TreeVo> children, String value) { for (TreeVo child : children) { if (child.getName().equals(value) || (child.getChildren().size() > 0 && contains(child.getChildren(), value))) { return t

  • python实现在目录中查找指定文件的方法

    本文实例讲述了python实现在目录中查找指定文件的方法.分享给大家供大家参考.具体实现方法如下: 1. 模糊查找 复制代码 代码如下: import os from glob import glob #用到了这个模块 def search_file(pattern, search_path=os.environ['PATH'], pathsep=os.pathsep):     for path in search_path.split(os.pathsep):         for mat

  • 在Ruby中查找和执行方法

    当调用一个方法时,Ruby会做两件事. 1.找到这个方法.这个方法称为方法查找. 2.执行这个方法.为了做到这点,Ruby需要一个叫做self的东西. 这样的一个过程--发现一个方法再执行之--在每种面向对象语言中都会发生.不过,对于像Ruby这样非常动态的语言,深入理解这个过程显得尤为重要.你有没有好奇过一个方法究竟定义在哪里呢?如果有,那绝对应该深入理解方法查找及self. 当调用一个方法时,Ruby会在对象的类中查找那个方法.不过,在给出更复杂的例子之前,你需要了解两个新概念:接收者(re

  • 从SAM文件中查找密码

    从SAM文件中查找密码     采用特殊软件,从本地系统或远程系统的SAM文件中,采用密码字典或暴力破解方法,查找出登录密码.此种方法可以找出原始是用户名何密码,但是,按机器性能不同,可能需时很长.     这类软件比较出名的有L0phtCrack (LC).LCP和SamInside pro,三个软件要求有管理员(Administrator)权限才能安装,如果没有管理员权限(登录密码丢失了),怎么安装?可以借助DreamPackPL进入Windows安装,或用Bart PE或Windows P

  • php在字符串中查找另一个字符串

    <a href="./">返回列表</a><br> <form action="<?echo $PHP_SELF;?>" method="post"> 在<input type="text" name="string" value="<?echo $string;?>">中查找<input type

  • php实现指定字符串中查找子字符串的方法

    本文实例讲述了php实现指定字符串中查找子字符串的方法.分享给大家供大家参考.具体分析如下: 对strpos()函数可以用来在php中查找子字符串.strpos()函数将试图找到子字符串在源字符串中首次出现的位置.如果找到了,它会返回一个非负整数表示子字符串出现的位置. 否则它会返回一个布尔值false. <?php $haystack1 = "2349534134345w3mentor16504381640386488129"; $haystack2 = "w3men

  • php实现在多维数组中查找特定value的方法

    本文实例讲述了php实现在多维数组中查找特定value的方法.分享给大家供大家参考.具体如下: 最近做项目,需要从多维数组中查找是否含有特定的key和其对应特定的value,并清除该条数据,比如: $arr = array( //为了看的方便,数组表达形式不对 0=>array(id =>1,name =>"li") 1=>array(id =>2,name =>"na") 2=>array(id =>3,name =

  • php在数组中查找指定值的方法

    本文实例讲述了php在数组中查找指定值的方法.分享给大家供大家参考.具体如下: php中有两个函数可以判断数组中是否包含指定的值,分别是:array_search($value, $array)和in_array($value, $array),array_search可以找出指定的值在数组中出现的位置,in_array函数只判断数组中是否存在指定的值,返回bool值 <?php $array = array("Perl", "PHP", "Java

  • python实现在字符串中查找子字符串的方法

    本文实例讲述了python实现在字符串中查找子字符串的方法.分享给大家供大家参考.具体如下: 这里实现python在字符串中查找子字符串,如果找到则返回子字符串的位置,如果没有找到则返回-1 S = 'xxxxSPAMxxxxSPAMxxxx' where = S.find('SPAM') # search for position print where # occurs at offset 4 希望本文所述对大家的Python程序设计有所帮助.

随机推荐