Java 给定树形数据集合,获取所有目标路径
Java 给定树形数据集合,获取所有目标路径
1、工具类
/**
* @Author dw
* @Description 给定树形数据集合,获取所有目标路径
* @Date 2024/6/24 20:48
* @Version 1.0
*/
public class TreeDataUtil {
/**
* 获取所有的目标路径
*
* @param treeData 树形数据集合
* @param targetCodes 目标叶子节点
* @return 所有目标路径
*/
public static List<String> getPaths(List<TreeNode> treeData, Set<String> targetCodes) {
ArrayList<String> paths = new ArrayList<>();
for (TreeNode treeDatum : treeData) {
List<String> path = getPath(treeDatum, targetCodes);
if (CollectionUtils.isNotEmpty(path)) {
paths.addAll(path);
}
}
return paths;
}
public static List<String> getPath(TreeNode root, Set<String> targetCodes) {
List<List<String>> pathsToLeaves = getPathsToLeaves(root, targetCodes);
if (CollectionUtils.isEmpty(pathsToLeaves)) {
return null;
}
return pathsToLeaves.stream().map(path -> String.join("/", path)).collect(Collectors.toList());
}
/**
* 根据叶子节点编码集合获取树的路径
* @param root 树的根节点
* @param targetCodes 目标叶子节点的编码集合
* @return 从根到所有目标节点的路径列表
*/
public static List<List<String>> getPathsToLeaves(TreeNode root, Set<String> targetCodes) {
List<List<String>> pathList = new ArrayList<>();
findPaths(root, targetCodes, new ArrayList<>(), pathList);
return pathList;
}
/**
* 查找叶子节点路径
*
* @param node 当前节点
* @param targetCodes 目标节点编码
* @param currentPath 当前路径
* @param pathList 结果路径列表
*/
private static void findPaths(TreeNode node,
Set<String> targetCodes,
List<String> currentPath,
List<List<String>> pathList) {
// 添加当前节点到路径中
currentPath.add(node.getLabel());
// 如果当前节点是目标节点之一,保存路径
if (targetCodes.contains(node.getValue())) {
pathList.add(new ArrayList<>(currentPath));
}
// 遍历子节点
if (CollectionUtils.isNotEmpty(node.getChildren())) {
for (TreeNode child : node.getChildren()) {
findPaths(child, targetCodes, currentPath, pathList);
}
}
// 回溯,从路径中移除当前节点(为下一个兄弟节点做准备)
currentPath.remove(currentPath.size() - 1);
}
}
2、测试
@Test
public void test18(){
String treeDataStr = "[\n" +
" {\n" +
" \"value\": \"1.0\",\n" +
" \"label\": \"1.0\",\n" +
" \"children\": [\n" +
" {\n" +
" \"value\": \"102\",\n" +
" \"label\": \"电梯维护\",\n" +
" \"children\": [\n" +
" {\n" +
" \"value\": \"009\",\n" +
" \"label\": \"电梯临时维护(009)\",\n" +
" \"children\": null\n" +
" },\n" +
" {\n" +
" \"value\": \"010\",\n" +
" \"label\": \"电梯长期故障(010)\",\n" +
" \"children\": null\n" +
" }\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"value\": \"103\",\n" +
" \"label\": \"设备故障\",\n" +
" \"children\": [\n" +
" {\n" +
" \"value\": \"011\",\n" +
" \"label\": \"无板无机(011)\",\n" +
" \"children\": null\n" +
" },\n" +
" {\n" +
" \"value\": \"022\",\n" +
" \"label\": \"无机器(022)\",\n" +
" \"children\": null\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"value\": \"2.0\",\n" +
" \"label\": \"2.0\",\n" +
" \"children\": [\n" +
" {\n" +
" \"value\": \"102\",\n" +
" \"label\": \"电梯维护\",\n" +
" \"children\": [\n" +
" {\n" +
" \"value\": \"1001\",\n" +
" \"label\": \"电梯装修(1001)\",\n" +
" \"children\": null\n" +
" },\n" +
" {\n" +
" \"value\": \"1002\",\n" +
" \"label\": \"电梯年检(1002)\",\n" +
" \"children\": null\n" +
" }\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"value\": \"106\",\n" +
" \"label\": \"其他\",\n" +
" \"children\": [\n" +
" {\n" +
" \"value\": \"1016\",\n" +
" \"label\": \"点位编码缺失(1016)\",\n" +
" \"children\": null\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]";
List<TreeNode> treeData = JSON.parseArray(treeDataStr, TreeNode.class);
HashSet<String> targetCodes = Sets.newHashSet("009", "011", "1016");
System.out.println(TreeDataUtil.getPaths(treeData, targetCodes));
}