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中查找某节点下的所有数据操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
以上是 list转tree和list中查找某节点下的所有数据操作 的全部内容, 来源链接: utcz.com/z/311763.html