关于数据组装我有话要说

本文介绍了一种优化数据拼装的方法,通过将集合转换为id->object的map,再遍历list进行拼装,将时间复杂度从O(n^2)降低至O(2n),适用于Java后端处理一对多或树形结构数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个问题肯定不止我一个人遇到,也肯定不止我一个人想到;
我是菜鸟,觉得我写的水的话请轻喷^_^;

作为一个java程序猿,每天的工作就是和数据库打交道,把数据查出来拼装成前端需要的样子,并返回给前端;
如果只是简单的单表,或者是一对一的连表查询都还好说(不建议连表查询,之后会说),很多时候碰到一对多的表,或者是树形结构.就不能简单的用sql搞定,就需要查出来在内存中进行拼装.本篇文章就是想讲述下我对数据拼装的心得;


先说结论:

总体思想是先把一个集合转换成id->object的map,在遍历一个list,然后从map中找到关联类并组装


在我早些时候写一对多的数据拼装时是这样写的,现在也会见到很多同事这样写;

public Parents combinationWithLoop(List<Parent> parents,List<Sons> sons){
	for(Parent parent: parents){
		for(Son son: sons){
			if(Object.equals(son.getPid(), parent.getId()){
				parent.addson(son);
				break;
			}
		}
	}
	return parent;
}

嵌套循环.时间复杂度parent.size*sons.size;
而且对于每次sons的遍历只有一次是有实际数据操作的,其他情况就只是路过而已;做了无意义的事情;


接下来改写下:

public Parents combinationWithMap(List<Parent> parents,List<Sons> sons){
   Map<String,Parent> parentMap = parents.stream().collect(Parent::getId,t->t);
   		for(Son son:Sons){
   			parentMap.get(son.getPid()).addSon(son);
   		}
   return parents;
}

时间复杂度变成parents.size+sons.size;(忽略map的常数级时间复杂度)
虽然空间复杂度会增加(类本身没有复制,增加的只是map的指针数据)
简单的改写.效率提升一个数量级;


同样树形结构也是可以做一样的操作;

	public Node buildTree(List<Node> nodes){
		Map<String,Node> nodeMap = nodes.stream().collect(Collectors.toMap(Node::getId,t->t);
		Node rootNode = null;
		for(Node node : nodes){
			Node pNode = nodeMap.get(node.getPid);
			if(pNode == null){
				rootNode = node; 
			} else{
				pNode.addSon(node);
			}
		}
		return rootNode;
	}

这样避免了递归,多重嵌套循环什么的问题.

总结

正如开题所说,把时间复杂度O(n^2)变成O(2n);
这个思想不仅仅只是后台有用,前端一样也可以使用,js的Object获取指定key的时间复杂度应该也是O(1) (我记得有查过);
同样的…作为树形结构的上下节点查找.使用遍历方法是很低效的.完全可以转换成两个Map;
nodeMap = id->node;
sonsMap = pid->List<node>;
这样你知道任意一个节点都可以很方便的找到
父节点(nodeMap.get(node.getPid())),
兄弟节点(sonsMap.get(node.getPid())),
子节点(sonsMap.get(node.getId()));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值