树形结构排序

87 阅读1分钟

需求描述

  1. 目前正在做一个根据两个环境表数据对比结果,生成增删改语句的需求项目
  2. 如果一条数据(根据业务主键唯一确定一条数据)源环境没有,目标环境有,则生成新增语句
  3. 生成的新增语句中id字段要自动生成
  4. 此时就产生了一个问题,如果两条数据有前后依赖关系,比如数据中有一个parentId字段,那么父类数据就需要优先插入,先生成id, 供子类数据使用,否则子类数据先插入,无法知道parentId

需求分析

  1. 此问题,是一个纯算法问题
  2. 算法中要考虑效率,尽量减少循环,中间结果可以记录下来,供后续使用

具体实现

/**  
* 树形结构排序  
*  
* @param sourceList  
* @param pidFieldName  
*/  
public static void sortByTopLevel(List<Map<String, Object>> sourceList, String pidFieldName) {  
    if (CollectionUtils.isEmpty(sourceList) || sourceList.size() == 1) {  
        return;  
    }  
    Map<Long, Map<String, Object>> itemMap = new HashMap<>();  
    for (Map<String, Object> item : sourceList) {  
        Long id = MapUtils.getLong(item, ID);  
        itemMap.put(id, item);  
    }  
  
    List<Map<String, Object>> sortedList = new ArrayList<>();  

    for (Map<String, Object> item : sourceList) {  
        Long pid = MapUtils.getLong(item, pidFieldName);  
        if (pid == null || !itemMap.containsKey(pid)) {  
            addSortedItem(item, itemMap, sortedList, pidFieldName);  
        }  
    }  
    sourceList.clear();  
    sourceList.addAll(sortedList);  
}  
  
private static void addSortedItem(Map<String, Object> item, Map<Long, Map<String, Object>> itemMap, List<Map<String, Object>> sortedList, String pidFieldName) {  
    sortedList.add(item);  
    Long id = MapUtils.getLong(item, ID);  
    for (Map.Entry<Long, Map<String, Object>> entry : itemMap.entrySet()) {  
        Long pid = MapUtils.getLong(entry.getValue(), pidFieldName);  
        if (pid != null && pid.equals(id)) {  
            addSortedItem(entry.getValue(), itemMap, sortedList, pidFieldName);  
        }  
    }  
}