1. 程式人生 > 其它 >史上最簡單的JAVA集合(List)轉樹(Tree)方法

史上最簡單的JAVA集合(List)轉樹(Tree)方法

技術標籤:開發工具javalambda

import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 平行集合轉Tree集合測試示例
 *
 * @author 54lxb
 * @version 1.0.0
 * @apiNote Talk is cheap, show me the code!
 * @since 2021-02-01 17:32
 */
public class ListToTreeDemo {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        List<DemoData> demoData = transToTree(data());
        long end = System.currentTimeMillis();
        System.out.println("耗時:"+ (end - start) + "ms,轉換後的資料:\n" + JSON.toJSONString(demoData));
    }

    /**
     * 將資料轉換為樹型結構
     *
     * @param sources sources
     * @return {@link List<DemoData>}
     */
    public static List<DemoData> transToTree(List<DemoData> sources) {
        if (CollectionUtils.isEmpty(sources)) {
            return Collections.emptyList();
        }
        Map<Integer, DemoData> sourceMap = sources.stream().collect(Collectors.toMap(DemoData::getId, e -> e));
        Map<Integer, List<DemoData>> pIdToChildrenListMap = sources.stream().collect(Collectors.groupingBy(DemoData::getPid));
        List<Integer> willBeRemovedIdList = new LinkedList<>();
        for (Map.Entry<Integer, List<DemoData>> entry : pIdToChildrenListMap.entrySet()) {
            DemoData demoData = sourceMap.get(entry.getKey());
            if (demoData == null) {
                continue;
            }
            demoData.setChildren(entry.getValue().stream().sorted(Comparator.comparing(DemoData::getSort)).collect(Collectors.toList()));
            willBeRemovedIdList.add(entry.getKey());
        }
        willBeRemovedIdList.forEach(pIdToChildrenListMap::remove);
        // 獲取頂級
        return pIdToChildrenListMap.values().stream().flatMap(Collection::stream).sorted(Comparator.comparing(DemoData::getSort)).collect(Collectors.toList());
    }

    /**
     * 生成測試資料
     *
     * @return {@link List<DemoData>}
     */
    public static List<DemoData> data() {
        List<DemoData> results = new LinkedList<>();
        results.add(new DemoData(1, 0, "CE_SHI_A", "測試A", 1));
        results.add(new DemoData(2, 1, "CE_SHI_A_001", "測試A001", 2));
        results.add(new DemoData(3, 1, "CE_SHI_A_002", "測試A002", 3));
        results.add(new DemoData(4, 1, "CE_SHI_A_003", "測試A003", 4));

        results.add(new DemoData(5, 0, "CE_SHI_B", "測試B", 5));
        results.add(new DemoData(6, 5, "CE_SHI_B_001", "測試B001", 6));
        results.add(new DemoData(7, 5, "CE_SHI_B_002", "測試B002", 7));
        results.add(new DemoData(8, 5, "CE_SHI_B_003", "測試B003", 8));

        results.add(new DemoData(9, 2, "CE_SHI_A01", "測試A01", 9));
        results.add(new DemoData(10, 2, "CE_SHI_A02_001", "測試A02001", 10));
        results.add(new DemoData(11, 2, "CE_SHI_A03_002", "測試A03002", 11));
        results.add(new DemoData(12, 2, "CE_SHI_A04_003", "測試A04003", 12));

        results.add(new DemoData(13, 6, "CE_SHI_B01", "測試B01", 13));
        results.add(new DemoData(14, 6, "CE_SHI_B02_001", "測試B02001", 14));
        results.add(new DemoData(15, 6, "CE_SHI_B03_002", "測試03B002", 15));
        results.add(new DemoData(16, 6, "CE_SHI_B04_003", "測試B04003", 16));
        return results;
    }

}

@Data
@AllArgsConstructor
@NoArgsConstructor
class DemoData {
    /**
     * ID
     */
    private Integer id;
    /**
     * 父級ID
     */
    private Integer pid;
    /**
     * 編碼
     */
    private String code;
    /**
     * 名字
     */
    private String name;
    /**
     * 排序編碼
     */
    private Integer sort;
    /**
     * 子節點資料
     */
    private List<DemoData> children;

    public DemoData(Integer id, Integer pid, String code, String name, Integer sort) {
        this.id = id;
        this.pid = pid;
        this.code = code;
        this.name = name;
        this.sort = sort;
    }
}