使用map超过1个深度级别,从csv转换为json

我有一个csv文件,其内容如下:

Fruit, Mango Fruit, Apple Car, Audi Apple, Red Color, Brown 

我想最终以这样的格式转换它:

 "hierarchy" : [{ "label": "Fruit", "children" : [ {label: "Mango"}, {label: "Apple", "children": [ {label:"Red"}]} ] }, { "label" : "Car", "children" : [ {label: "Audi"} ] }, { "label" : "Color", "children" : [ {label: "Brown"} ] }] 

为此,我在地图中插入了值:

 StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append("\n"); line = br.readLine(); } String[] contents=(sb.toString().split("\n")); String[] newContents; Map<String, List> myMaps = new LinkedHashMap<String, List>(); for(String s : contents) { newContents= s.split(","); if (!myMaps.containsKey(newContents[0])) { myMaps.put(newContents[0], new ArrayList()); } myMaps.get(newContents[0]).add(newContents[1]); } 

这基本上将文件转换为父(键)和子(值)forms的映射。 然而,我想知道如何处理超过1级深度的情况 – 例如在我给定的csv中? 地图是否适用于这种情况还是有更好的方法?

您的JSON结构看起来更像一棵树,可以被设计为一个类:

 public class Node { private String label; private List children; // can also be of type Node[] // getters, setters } 

那么层次结构是一个数组或节点列表

列表比arrays更受欢迎,因为它在儿童群体中更容易使用

更新:有关如何使用Node类填充树的完整示例:

 public class Node { private String label; private List children = new ArrayList<>(); // to avoid checks for null public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public List getChildren() { return children; } public void setChildren(List children) { this.children = children; } } class Converter { public List fromCsvFile(String filename) throws IOException { Node root = new Node(); BufferedReader input = new BufferedReader(new FileReader(filename)); String[] entry; String line = input.readLine(); while (line != null) { entry = line.split(","); // find or create Node node = findByLabel(root, entry[0]); if (node == null) { // top level node = new Node(); node.setLabel(entry[0]); root.getChildren().add(node); } // add child Node child = new Node(); child.setLabel(entry[1]); node.getChildren().add(child); // next line line = input.readLine(); } return root.getChildren(); } public Node findByLabel(Node node, String label) { if (label.equals(node.getLabel())) { return node; } for (Node child : node.getChildren()) { // recursion Node found = findByLabel(child, label); if (found != null) { return found; } } return null; } } 

注意:您不需要显式Node ,并且可以使用Map ,其中值可以包含嵌套映射,或者子列表,或者标签的String值。 但使用显式类更清晰。

除了树中现有节点的递归查找之外,还可以创建一个独立的平面集合(Map)来加速查找:

 class Converter { public List fromCsvFile(String filename) throws IOException { Node root = new Node(); Map existingNodes = new HashMap<>(); BufferedReader input = new BufferedReader(new FileReader(filename)); String[] entry; String line = input.readLine(); while (line != null) { entry = line.split(","); // find or create Node node = existingNodes.get(entry[0]); if (node == null) { // new top level node node = new Node(); node.setLabel(entry[0]); root.getChildren().add(node); existingNodes.put(entry[0], node); } // add child Node child = new Node(); child.setLabel(entry[1]); node.getChildren().add(child); existingNodes.put(entry[1], child); // next line line = input.readLine(); } return root.getChildren(); } } 

仅供参考: 完整示例

地图很好。 只需使用递归函数来编写更深层次。

尝试这个。

 String csv = "" + "Fruit, Mango\n" + "Fruit, Apple\n" + "Car, Audi\n" + "Apple, Red\n" + "Color, Brown\n" + "Red, Fire\n"; Set topLevels = new LinkedHashSet<>(); Set notTopLevels = new LinkedHashSet<>(); Map> labels = new LinkedHashMap<>(); try (BufferedReader reader = new BufferedReader(new StringReader(csv))) { String line; while ((line = reader.readLine()) != null) { String[] fields = line.split("\\s*,\\s*"); Map value = labels.computeIfAbsent( fields[1], k -> new LinkedHashMap()); labels.computeIfAbsent( fields[0], k -> new LinkedHashMap()) .put(fields[1], value); topLevels.add(fields[0]); notTopLevels.add(fields[1]); } } Map hierarchy = new LinkedHashMap<>(); topLevels.removeAll(notTopLevels); for (String s : topLevels) hierarchy.put(s, labels.get(s)); System.out.println(hierarchy); 

结果:

 {Fruit={Mango={}, Apple={Red={Fire={}}}}, Car={Audi={}}, Color={Brown={}}}