如何使用Java读取文件树形结构并转换为Test对象列表
问题分析与解决方案
需求说明
输入文本文件包含两部分内容:
- 带缩进层级的树形节点描述,包含节点名、类型、描述
- 节点完整路径对应的键值对
文件内容如下:
parent Type short description1 .firstChild Type short description2 .firstNephew Type short description3 .secondChild Type short description4 .firstNephew Type short description5 .secondNephew Type short description6 parent.firstChild = value1 parent.firstChild.firstNephew = value2 parent.secondChild = value3 parent.secondChild.firstNephew = value4 parent.secondChild.secondNephew = value5
需要生成Test对象列表,每个对象包含节点短名称、类型、对应值、描述,最终输出需匹配节点与值的对应关系。
现有代码的问题
当前代码仅处理了树形描述部分,未解析值映射内容,也未关联节点的完整路径与对应值,同时没有处理缩进层级来构建节点的完整路径,无法生成符合预期的对象列表。
完善后的代码
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; import java.util.stream.Collectors; public class Test { private String name; private String type; private String value; private String description; public Test(String name, String type, String value, String description) { this.name = name; this.type = type; this.value = value; this.description = description; } @Override public String toString() { return name + ", " + type + ", " + value + ", " + description; } } class Main { // 临时存储节点的完整路径对应的短名称、类型、描述 private static class NodeMeta { String shortName; String type; String description; NodeMeta(String shortName, String type, String description) { this.shortName = shortName; this.type = type; this.description = description; } } public static void main(String[] args) { try { // 读取所有非空行 List<String> allLines = Files.lines(Paths.get("files/file.txt")) .filter(line -> !line.trim().isEmpty()) .collect(Collectors.toList()); // 分割树形描述和值映射部分 int splitIndex = 0; while (splitIndex < allLines.size() && !allLines.get(splitIndex).contains("=")) { splitIndex++; } List<String> treeLines = allLines.subList(0, splitIndex); List<String> valueLines = allLines.subList(splitIndex, allLines.size()); // 解析树形描述,构建完整路径到节点元数据的映射 Map<String, NodeMeta> nodeMetaMap = new HashMap<>(); Deque<String> parentPathStack = new ArrayDeque<>(); for (String line : treeLines) { int indent = line.length() - line.trim().length(); String[] parts = line.trim().split(" +", 3); String rawName = parts[0]; String type = parts[1]; String description = parts[2]; String shortName = rawName.startsWith(".") ? rawName.substring(1) : rawName; String fullPath; if (indent == 0) { // 根节点处理 fullPath = shortName; parentPathStack.clear(); parentPathStack.push(fullPath); } else { // 根据缩进匹配父节点 while (parentPathStack.size() > 1) { int expectedLevel = (parentPathStack.size() - 1) * 3; if (indent <= expectedLevel) { parentPathStack.pop(); } else { break; } } fullPath = parentPathStack.peek() + "." + shortName; parentPathStack.push(fullPath); } nodeMetaMap.put(fullPath, new NodeMeta(shortName, type, description)); } // 解析值映射,构建路径到值的映射 Map<String, String> valueMap = new HashMap<>(); for (String line : valueLines) { String[] parts = line.split(" = ", 2); valueMap.put(parts[0].trim(), parts[1].trim()); } // 生成Test对象列表 List<Test> testList = new ArrayList<>(); for (Map.Entry<String, NodeMeta> entry : nodeMetaMap.entrySet()) { String fullPath = entry.getKey(); NodeMeta meta = entry.getValue(); String value = valueMap.getOrDefault(fullPath, null); testList.add(new Test(meta.shortName, meta.type, value, meta.description)); } // 输出结果 testList.forEach(System.out::println); } catch (IOException e) { e.printStackTrace(); } } }
代码关键点说明
- 层级解析:用栈维护当前节点的父路径,通过缩进量判断节点层级,生成每个节点的完整路径。
- 数据映射:分别将树形描述、值映射存储为Map,便于后续关联匹配。
- 对象生成:遍历树形节点的完整路径,从值映射中获取对应值,最终生成
Test对象列表。
注:若需完全匹配你给出的预期输出(根节点parent对应value1等),需调整值映射的匹配逻辑(例如将子节点的值关联到父节点),这需要根据实际业务需求修改,当前代码严格遵循文件中的路径与值的对应关系。
内容的提问来源于stack exchange,提问作者Teo
相关产品推荐
相关产品推荐

