史上最簡單的JAVA集合(List)轉樹(Tree)方法
阿新 • • 發佈:2021-02-03
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; } }