java List轉Tree簡單實現TreeUtils.java

前言

我們在平時開發中,難免會遇到一些list轉tree的情況,例如省市區及區下面的一些區域,就需要用到樹的形式,而我們的原始數據爲了存儲方便一般拿出來都是list的形式,這時候就需要轉換

構造對象

這裏的pId表示上級節點的id,設定頂級節點的pId = 0

@Data
public class TreeNode {
    private Long id;
    private Long pId;
    private String name;
    private List<TreeNode> child;
}

分析邏輯

入參是一個沒有chid的List< TreeNode>,包含所有層級的節點

  1. 先把list按照pid分組,value則是pid對應的child
  2. 構造循環的條件:當沒有下級節點的時候
  3. 循環內封裝數據

實現方法

 public static List<TreeNode> buildTree(List<TreeNode> list) {
 	// 數據校驗	
	if (CollectionUtils.isEmpty(list)) {
		return Collections.emptyList();
	}
	// 過濾掉null並按照pId分組
	Map<Long, List<TreeNode>> map = list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(TreeNode::getPId));
	 // 再校驗一次
	if (MapUtils.isEmpty(map)) {
		return Collections.emptyList();
	}
	// 獲取一級節點,樹的根節點
	List<TreeNode> res = map.get(0L);
	// 父級節點
	List<TreeNode> parent = res;
	while (true) {
		List<TreeNode> temp = new ArrayList<>();
		// 遍歷父級節點
		for (TreeNode treeNode : parent) {
			Long pId = treeNode.getId();
			// 封裝child
			if (map.containsKey(pId)) {
				List<TreeNode> child = map.get(pId);
				treeNode.setChild(child);
				temp.addAll(child);
			}
		}
		// 直到沒有子節點
		if (CollectionUtils.isEmpty(temp)) {
			break;
		}
		// 繼續下一次循環
		parent = temp;
	}
	return res;
}

有點沒有看明白,驗證確實可用。

 

 

 

TreeUtils.java

package com.imddy.sc.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TreeUtils {

	public static void main(String[] args) throws JsonProcessingException {

		TreeNode node4 = new TreeNode(4, "宜昌市", 1);
		TreeNode node5 = new TreeNode(5, "上海市", 0);
		TreeNode node6 = new TreeNode(6, "靜安區", 5);
		TreeNode node7 = new TreeNode(7, "青浦區", 5);
		TreeNode node8 = new TreeNode(8, "黃浦區", 5);
		TreeNode node16 = new TreeNode(16, "渝中區", 10);
		TreeNode node17 = new TreeNode(17, "渝北區", 10);
		TreeNode node14 = new TreeNode(14, "武侯區", 11);
		TreeNode node15 = new TreeNode(15, "高新區", 11);
		TreeNode node18 = new TreeNode(18, "沙坪壩區", 10);
		TreeNode node9 = new TreeNode(9, "四川省", 0);
		TreeNode node10 = new TreeNode(10, "重慶市", 0);
		TreeNode node11 = new TreeNode(11, "成都市", 9);
		TreeNode node12 = new TreeNode(12, "達州市", 9);
		TreeNode node13 = new TreeNode(13, "通川區", 12);
		TreeNode node0 = new TreeNode(0, "中國", -1);
		TreeNode node1 = new TreeNode(1, "湖北省", 0);
		TreeNode node2 = new TreeNode(2, "武漢市", 1);
		TreeNode node3 = new TreeNode(3, "洪山區", 2);

		List<TreeNode> list = new ArrayList<>();

		list.add(node3);
		list.add(node4);
		list.add(node1);
		list.add(node2);
		list.add(node5);
		list.add(node6);
		list.add(node0);
		list.add(node7);
		list.add(node8);
		list.add(node9);
		list.add(node10);
		list.add(node11);
		list.add(node12);
		list.add(node13);
		list.add(node14);
		list.add(node15);
		list.add(node16);
		list.add(node17);
		list.add(node18);

		ObjectMapper objectMapper = new ObjectMapper();
		objectMapper.setSerializationInclusion(Include.NON_EMPTY);
		objectMapper.setSerializationInclusion(Include.NON_NULL);

		List<TreeNode> nodes99 = listToTreeByMap(list, 9);
		System.out.println(JSON.toJSONString(nodes99));
		System.out.println(objectMapper.writeValueAsString(nodes99));
		System.out.println("-----------------------------------------------------------------------");
		List<TreeNode> nodes100 = listToTreeByMap(list, 10);
		System.out.println(JSON.toJSONString(nodes100));
		System.out.println(objectMapper.writeValueAsString(nodes100));
		System.out.println("-----------------------------------------------------------------------");
		List<TreeNode> nodes101 = listToTreeByMap(list, 0);
		System.out.println(JSON.toJSONString(nodes101));
		System.out.println(objectMapper.writeValueAsString(nodes101));
		System.out.println("-----------------------------------------------------------------------");
		List<TreeNode> nodes102 = listToTreeByMap(list, -1);
		System.out.println(JSON.toJSONString(nodes102));
		System.out.println(objectMapper.writeValueAsString(nodes102));
	}

	public static List<TreeNode> listToTreeByMap(List<TreeNode> list, Integer pid) {
		// 數據校驗
		if (CollectionUtils.isEmpty(list)) {
			return Collections.emptyList();
		}
		// 過濾掉null並按照pId分組
		Map<Integer, List<TreeNode>> map = list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(TreeNode::getPid));
		// 再校驗一次
		if (CollectionUtils.isEmpty(map)) {
			return Collections.emptyList();
		}
		// 獲取一級節點,樹的根節點
		List<TreeNode> res = map.get(pid);
		// 父級節點
		List<TreeNode> parent = res;
		while (true) {
			List<TreeNode> temp = new ArrayList<>();
			// 遍歷父級節點
			for (TreeNode treeNode : parent) {
				Integer pId = treeNode.getId();
				// 封裝child
				if (map.containsKey(pId)) {
					List<TreeNode> child = map.get(pId);
					treeNode.setChildren(child);
					temp.addAll(child);
				}
			}
			// 直到沒有子節點
			if (CollectionUtils.isEmpty(temp)) {
				break;
			}
			// 繼續下一次循環
			parent = temp;
		}
		return res;
	}

}

對應的TreeNode.java

package com.imddy.sc.utils;

import java.util.List;

import lombok.Data;

@Data
public class TreeNode {

	private Integer id;
	private String city;
	private Integer pid;

	private List<TreeNode> children;

	public TreeNode(Integer id, String city, Integer pid) {
		this.id = id;
		this.city = city;
		this.pid = pid;
	}

	
	
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章