城市数据库以id,name,parentid 的方式存储数据,实体类如下:
City{
id
name
parentid
List<City> childcitys;
}
数据量大概有3000,公司原以foreach遍历所有数据,代码如下:
public static <T extends TreeEntity> List<T> buildTreeData(List<T> srcList){
List<T> desList = new ArrayList<>();
for (T obj: srcList) {
obj.setChildren(null);
if (StringUtils.isBlank(obj.getParentId()) || "0".equals(obj.getParentId())){//根节点
obj.setChildren(getChildren(obj.getId(), srcList));
desList.add(obj);
}
}
}
public static <T extends TreeEntity> List<T> getChildren(String id, List<T> srcList){
if (srcList == null || srcList.isEmpty()) return null;
List<T> _srcList = new ArrayList<>(srcList);
List<T> children = new ArrayList<>();
for (Iterator<T> iterator = _srcList.iterator(); iterator.hasNext();){
T obj = iterator.next();
T newObj = (T) BeanUtils.instantiate(obj.getClass());
BeanUtils.copyProperties(obj, newObj);
String pId = newObj.getParentId();
if(StringUtils.isNotEmpty(pId) && pId.equals(id)){
newObj.setChildren(getChildren(newObj.getId(), _srcList));
children.add(newObj);
iterator.remove();
}
}
return children;
}
乍一看,可实现级联存放,但这段代码,3000条数据估计要运行13秒,前端还等着你的接口返回数据呢。于是将它进行优化,改动代码:
public static <T extends TreeEntity> List<T> buildTreeData(List<T> srcList){
List<T> desList = new ArrayList<>();
Map<String,List<T>> map = new HashMap<String,List<T>>();
List<T> l = null;
for(T obj : srcList){
String key = StringUtils.isBlank(obj.getParentId())?"0":obj.getParentId();
if(map.get(key)==null){
l = new ArrayList<T>();
}else{
l = map.get(key);
}
l.add(obj);
map.put(key,l);
}
for(T obj2 : map.get("0")){//最顶级
if(obj2==null){
return null;
}
obj2.setChildren(getChild(map,obj2.getId()));
desList.add(obj2);
}
}
public static <T extends TreeEntity> List getChild(Map<String, List<T>> map, String i) {
if(map.get(i)==null){return null;}
List<T> childs = map.get(i);//取到子节点
try {
for(T obj : childs){
obj.setChildren(getChild(map,obj.getId()));
}
} catch (Exception e) {
e.printStackTrace();
}
return childs;
}
这一来,可减少了N次遍历,大大缩短了执行时间,具体多少秒可亲测,估计能缩短100倍。(不得不说HashMap真是个好东西)
如果有更好处理逻辑,还望不吝赐教