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

网友投稿 278 2022-11-22


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

类的实例化顺序

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

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

已知组织类Org{String id,String name,String parentId},现在一List中存放无序的Org数据,求一个组织id下的所有组织。

public static List childList=new ArrayList<>();

public static List findChild(List 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 sourceLit){

// 重根节点开始

for (TreeNode sourceNode : sourceLit){

if (sourceNode.getpId() == node.getId()){

if(node.getChildrenList() == null){

node.setChildrenList(new ArrayList());

}

node.getChildrenList().add(listToTree(sourceNode, sourceLit));

}

}

return node;

}

补充知识:java实现树数据Tree与List互转并逐级汇总节点的值(支持树节点多列统计)

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

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

构造一棵树的基本节点:

package com.example.demo.tree;

import saazpWjava.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 values=new ArrayList();

/**

* 当前节点所有子节点的值集合

*/

private List childrenMultiValues=new ArrayList();

/**

* 父节点ID

*/

private long pid;

/**

* 子节点集合对象

*/

private List children=new ArrayList();

/**

* 是否计算本身

*/

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 getValues() {

return values;

}

public void setValues(List values) {

this.values = values;

}

public List getChildrenMultiValues() {

return childrenMultiValues;

}

public void setChildrenMultiValues(List childrenMultiValues) {

this.childrenMultiValues = childrenMultiValues;

}

public long getPid() {

return pid;

}

public void setPid(long pid) {

this.pid = pid;

}

public List getChildren() {

return children;

}

public void setChildren(List 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 listToTree(List list,long rootId){

List tree=new ArrayList();

Map map = new HashMap();

// 将所有的数据,以键值对的形式装入map中

for (TreeNode node : list) {

// 去除冗余的子节点

node.setChildren(new ArrayList());

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 list){

if(list==null){

list=new ArrayList();

}

//设置当前节点的必要数据

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());

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 listToTreeWithSingleValue(List list,long rootId){

Map map = new HashMap();

// 将所有的数据,以键值对的形式装入map中

for (TreeNode node : list) {

// 去除冗余的子节点

node.setChildren(new ArrayList());

map.put(node.getId(), node);

}

List tree=listToTree(list,rootId);

/* // 存储最小子节点ID

Map leafList=new HashMap();

findMinNodes(tree.get(0),leafList,0);

// 设置每个节点的值

for (Long id_: leafList.keySet()) {

// 内部递归树的父节点层级多于2会存在重复计算

setParentNodeValue(map,id_);

}*/

// 存储最小子节点ID

Map leaf=new HashMap();

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 result=new ArrayList();

for (TreeNode node:map.values()) {

result.add(node);

}

return listToTree(result,rootId);

}

/**

* 转换数据格式并设置对应节点的值汇总到根节点

* @param tree

* @return

*/

public static List treeToListWithSingleValue(TreeNode tree){

List list=new ArrayList();

// 获取到List

treeToList(tree,list);

Map map = new HashMap();

// 将所有的数据,以键值对的形式装入map中

for (TreeNode node : list) {

// 去除冗余的子节点

node.setChildren(new ArrayList());

map.put(node.getId(), node);

}

/* // 存储最小子节点ID

Map leafList=new HashMap();

findMinNodes(tree,leafList,0);

// 设置每个节点的值

for (Long id_: leafList.keySet()) {

// 内部递归树的父节点层级多于2会存在重复计算

setParentNodeValue(map,id_);

}*/

// 存储最小子节点ID

Map leaf=new HashMap();

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 result=new ArrayList();

for (TreeNode node:map.values()) {

result.add(node);

}

return result;

}

/**

* 转换数据格式并设置对应节点的值汇总到根节点

* @param list

* @param rootId

* @param columns

* @return

*/

public static List listToTreeWithMultiValues(List list,long rootId,int columns){

Map map = new HashMap();

// 将所有的数据,以键值对的形式装入map中

for (TreeNode node : list) {

// 去除冗余的子节点

node.setChildren(new ArrayList());

map.put(node.getId(), node);

}

List tree=listToTree(list,rootId);

/* // 存储最小子节点ID

Map leafList=new HashMap();

findMinNodes(tree.get(0),leafList,0);

// 设置每个节点的值

for (Long id_: leafList.keySet()) {

// 内部递归树的父节点层级多于2会存在重复计算

setParentNodeMultiValues(map,id_);

}*/

// 存储最小子节点ID

Map leaf=new HashMap();

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 result=new ArrayList();

for (TreeNode node:map.values()) {

result.add(node);

}

return listToTree(result,rootId);

}

/**

* 转换数据格式并设置对应节点的值汇总到根节点

* @param tree

* @param columns

* @return

*/

public static List treeToListWithMultiValues(TreeNode tree,int columns){

List list=new ArrayList();

// 获取到List

treeToList(tree,list);

Map map = new HashMap();

// 将所有的数据,以键值对的形式装入map中

for (TreeNode node : list) {

// 去除冗余的子节点

node.setChildren(new ArrayList());

map.put(node.getId(), node);

}

/*

// 存储最小子节点ID

Map leafList=new HashMap();

findMinNodes(tree,leafList,0);

// 设置每个节点的值

for (Long id_: leafList.keySet()) {

// 内部递归树的父节点层级多于2会存在重复计算

setParentNodeMultiValues(map,id_);

}*/

// 存储最小子节点ID

Map leaf=new HashMap();

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 result=new ArrayList();

for (TreeNode node:map.values()) {

result.add(node);

}

return result;

}

/**

* 逐级追加设置节点的值(单个值)

* @param leaf

* @param map

*/

public static void setValuesToParentNode(Map leaf,Map map){

Map newLeaf=new HashMap();

// 设置每个节点的值

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 leaf,Map map){

Map newLeaf=new HashMap();

// 设置每个节点的值

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 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 newLeaf,Map 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(nodesaazpW.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 newLeaf,Map 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)saazpW;

//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());

tree.setPid(0);

List list =new ArrayList();

TreeNode node1=new TreeNode();

node1.setId(2);

node1.setLabel("子节点1");

node1.setValue(100);

node1.setMultiValues(new double[]{5,7,3});

node1.setChildrenMultiValues(new ArrayList());

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());

node2.setPid(1);

list.add(node2);

tree.setChildren(list);

List destList=new ArrayList();

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源码:点击进入


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot中打war包需要注意事项
下一篇:SpringBoot中整合knife4j接口文档的实践
相关文章

 发表评论

暂时没有评论,来抢沙发吧~