列表转树结构
逻辑上呈树结构的数据,诸如菜单,省市区,在数据库中单表存放,Java程序从数据库中读取出来这些数据时,是列表形式。列表转树结构使用双层for循环实现:
/**
* 节点组成树形结构,返回森林
*
* @param list 节点列表
* @param predicate 定义树的根节点
* @return 森林
*/
static <T extends ITree<T>> List<T> toForest(List<T> list, Predicate<T> predicate) {
for (T item : list) {
List<T> children = list.stream()
.filter(c -> Objects.equals(c.getParentId(), item.getId()))
.collect(Collectors.toList());
item.setChildren(children);
}
List<T> tree = list.stream().filter(predicate)
.collect(Collectors.toList());
return tree;
}
获取节点至根的路径
使用递归的样例代码如下:
/**
* 例如 areaCode=130400时,返回河北省邯郸市
* 例如 areaCode=130000时,返回河北省
*
* @param areaCode 省、市、区级编码
* @return 从省级全名拼接到areaCode全名的路径
*/
public String getPathFullname(String areaCode) {
AreaDict areaDict = dao.findByAreaCode(areaCode).orElse(null);
if (areaDict == null) return "";
if (!COUNTRY_CODE.equals(areaDict.getParentCode())) {
return getPathFullname(areaDict.getParentCode()) + areaDict.getFullname();
}
return areaDict.getFullname();
}
可以优化为使用双层for循环,list保存中间的迭代结果的方式,替代递归。
伪代码:
function(areaCode){
List list = new List();
list.add(areaCode)
while(list.tail is not root){
list.add(parent(list.tail))
}
return list.reverse().join()
}