java树型数据结构的数据向上汇总

今天有一个需求是一个项目分为好多个模块,最底层的模块由员工填写进度,进度填写后,上级模块自动算出进度,依次上推,页面如图

今天写了一个算法搞出来了,但是感觉有些繁琐,但是还没有想到更好的办法。

思路如下:

1、找到最底层叶子节点
2、从1中的结果中找到pid相同的叶子节点
3、计算结果到父节点中
4、将子节点放入到父节点中
5、将子节点从集合中删除,让其对应的父节点变成最底层子节点

循环以上过程

代码如下:

public class Test {

	
	
	public static void main(String[] args) {
		List<Goal> listGoal = new ArrayList<Goal>();
		Goal g1 = new Goal();
		g1.setId(1);
		g1.setParentId(0);
		g1.setGoalName("g1");
		Goal g2 = new Goal();
		g2.setId(2);
		g2.setParentId(1);
		g2.setGoalName("g2");
		Goal g3 = new Goal();
		g3.setId(3);
		g3.setParentId(2);
		g3.setGoalName("g3");
		Goal g4 = new Goal();
		g4.setId(4);
		g4.setParentId(2);
		g4.setGoalName("g4");
		Goal g5 = new Goal();
		g5.setId(5);
		g5.setParentId(3);
		g5.setGoalName("g5");
		g5.setAverageScore(98);
		Goal g6 = new Goal();
		g6.setId(6);
		g6.setParentId(1);
		g6.setGoalName("g6");
		Goal g7 = new Goal();
		g7.setId(7);
		g7.setParentId(3);
		g7.setGoalName("g7");
		Goal g8 = new Goal();
		g8.setId(8);
		g8.setParentId(7);
		g8.setGoalName("g8");
		g8.setAverageScore(90);
		Goal g9 = new Goal();
		g9.setId(9);
		g9.setParentId(7);
		g9.setGoalName("g9");
		g9.setAverageScore(77);
		Goal g10 = new Goal();
		g10.setId(10);
		g10.setParentId(4);
		g10.setGoalName("g10");
		Goal g11 = new Goal();
		g11.setId(11);
		g11.setParentId(10);
		g11.setGoalName("g11");
		g11.setAverageScore(85);
		Goal g12 = new Goal();
		g12.setId(12);
		g12.setParentId(7);
		g12.setGoalName("g12");
		g12.setAverageScore(80);
		Goal g13 = new Goal();
		g13.setId(13);
		g13.setParentId(6);
		g13.setGoalName("g13");
		g13.setAverageScore(94);
		listGoal.add(g1);
		listGoal.add(g2);
		listGoal.add(g3);
		listGoal.add(g4);
		listGoal.add(g5);
		listGoal.add(g6);
		listGoal.add(g7);
		listGoal.add(g8);
		listGoal.add(g9);
		listGoal.add(g10);
		listGoal.add(g11);
		listGoal.add(g12);
		listGoal.add(g13);
		Test t = new Test();
		
		Goal tempGoal = t.calculateValue(listGoal);
		t.printGoal(tempGoal);
	}
	
	//找到最底层的叶子节点
	public List<Goal> getBottomNode(List<Goal> listGoal) {
		Map<Integer, Goal> map = new HashMap<Integer, Goal>();
		for (Goal g : listGoal) {
			map.put(g.getId(), g);
		}
		
		for (Goal g : listGoal) {
			int pid = g.getParentId();
			if (map.containsKey(pid)) {
				map.remove(pid);
			}
		}
		
		return new ArrayList<Goal>(map.values());
	}
	
	public List<Goal> setParentValue(List<Goal> listAllGoal, List<Goal> listBottomGoal) {
		
		Map<Integer, List<Goal>> map = new HashMap<Integer, List<Goal>>();
		for (Goal g : listBottomGoal) {
			int pid = g.getParentId();
			List<Goal> listGoal = map.get(pid);
			if (listGoal == null) {
				listGoal = new ArrayList<Goal>();
			}
			listGoal.add(g);
			map.put(pid, listGoal);
		}
		
		for (Integer i : map.keySet()) {
			List<Goal> tempListGoal = map.get(i);
			int result = 0;
			for (Goal g : tempListGoal) {
				result += g.getAverageScore();
			}
			for (Goal g : listAllGoal) {
				int id = g.getId();
				if (id == i) {
					List<Goal> tempList = g.getListGoal();
					if (tempList != null) {
						tempListGoal.addAll(tempList);
					}
					g.setListGoal(tempListGoal);
					int score = g.getAverageScore();
					score = (score + result) / tempListGoal.size();
					g.setAverageScore(score);
				}
			}
		}
		
		for (Goal g : listBottomGoal) {
			listAllGoal.remove(g);
		}
		
		return listAllGoal;
	}
	
	public Goal calculateValue(List<Goal> listGoal) {
		if (listGoal.size() == 1) {
			return listGoal.get(0);
		} else {
			List<Goal> listBottomGoal = getBottomNode(listGoal);
			List<Goal> list = setParentValue(listGoal, listBottomGoal);
			return calculateValue(list);
		}
	}
	
	
	public void printGoal(Goal goal) {
		System.out.println(goal.getGoalName()+":"+goal.getAverageScore());
		List<Goal> listGoal = goal.getListGoal();
		if (listGoal == null || listGoal.size() == 0) {
			return;
		}
		for (Goal g : listGoal) {
			 printGoal(g);
		}
	}
	
}

运行结果如下:

g1:90
g2:87
g3:90
g7:82
g8:90
g9:77
g12:80
g5:98
g4:85
g10:85

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值