Java 使用map将csv转换为json,深度超过1级

Java 使用map将csv转换为json,深度超过1级,java,json,csv,hashmap,typeconverter,Java,Json,Csv,Hashmap,Typeconverter,我有一个csv文件,其内容如下: Fruit, Mango Fruit, Apple Car, Audi Apple, Red Color, Brown 我希望最终将其转换为如下格式: "hierarchy" : [{ "label": "Fruit", "children" : [ {label: "Mango"}, {label: "Apple", "children": [ {label:"Red"}]} ] }, { "label" : "Car", "c

我有一个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<String>> myMaps = new LinkedHashMap<String, List<String>>();


for(String s : contents)
{
  newContents= s.split(",");
    if (!myMaps.containsKey(newContents[0])) {
            myMaps.put(newContents[0], new ArrayList<String>());
        }
        myMaps.get(newContents[0]).add(newContents[1]);
}
StringBuilder sb=新建StringBuilder();
String line=br.readLine();
while(行!=null){
某人附加(行);
某人附加(“\n”);
line=br.readLine();
}
字符串[]内容=(sb.toString().split(“\n”);
字符串[]newContents;
Map myMaps=新建LinkedHashMap();
for(字符串s:内容)
{
newContents=s.split(“,”);
如果(!myMaps.containsKey(newContents[0])){
put(newContents[0],newarraylist());
}
myMaps.get(newContents[0]).add(newContents[1]);
}

这将基本上将文件转换为父(键)和子(值)形式的映射。然而,我想知道当深度超过1级时,如何处理这种情况——例如在我给定的csv中?映射在这种情况下有效吗?还是有更好的方法?

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

public class Node {
    private String label;
    private List<Node> children; // can also be of type Node[]

    // getters, setters
}
注意:您不需要显式的
节点
,您可以使用
映射
,其中值可以包含嵌套映射、子项列表或标签的字符串值。但是使用显式类更干净

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

class Converter {
    public List<Node> fromCsvFile(String filename) throws IOException {
        Node root = new Node();
        Map<String, Node> 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();
    }
}
类转换器{
CSVFile(字符串文件名)的公共列表引发IOException{
节点根=新节点();
Map existingNodes=new HashMap();
BufferedReader输入=新BufferedReader(新文件读取器(文件名));
字符串[]项;
String line=input.readLine();
while(行!=null){
条目=行分割(“,”);
//发现或创造
Node Node=existingNodes.get(条目[0]);
if(node==null){
//新的顶级节点
node=新节点();
node.setLabel(条目[0]);
root.getChildren().add(节点);
existingNodes.put(条目[0],节点);
}
//添加子项
节点子节点=新节点();
child.setLabel(条目[1]);
node.getChildren().add(子节点);
existingNodes.put(条目[1],子节点);
//下一行
line=input.readLine();
}
返回root.getChildren();
}
}

仅供参考:

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

试试这个

String csv = ""
    + "Fruit, Mango\n"
    + "Fruit, Apple\n"
    + "Car, Audi\n"
    + "Apple, Red\n"
    + "Color, Brown\n"
    + "Red, Fire\n";
Set<String> topLevels = new LinkedHashSet<>();
Set<String> notTopLevels = new LinkedHashSet<>();
Map<String, Map<String, Object>> 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<String, Object> value = labels.computeIfAbsent(
            fields[1], k -> new LinkedHashMap<String, Object>());
        labels.computeIfAbsent(
            fields[0], k -> new LinkedHashMap<String, Object>())
            .put(fields[1], value);
        topLevels.add(fields[0]);
        notTopLevels.add(fields[1]);
    }
}
Map<String, Object> hierarchy = new LinkedHashMap<>();
topLevels.removeAll(notTopLevels);
for (String s : topLevels)
    hierarchy.put(s, labels.get(s));
System.out.println(hierarchy);

要映射键值对,只有
java.util.map
接口。或者您可以使用Library它将如何映射多个深度级别?您可以使用
java.util.map
作为外部
map
的值来生成此格式的JSON?(它可以用于深度为1的情况,但是如何创建一个级别可以超过2的贴图?。@TeeJay类似的例子that@TeeJay如果在CSV文件的较低记录中,顶级节点突然被称为另一个节点的子节点,则重新组织树仍然是一个挑战,此时,节点应从
根节点
子节点移动到新节点子节点,这应在“添加子节点”逻辑之前完成。如果CSV上存在约束,则可以避免此操作,如按顺序提及子节点,对吗?(而不是下面记录中的其他地方?)例如:A、B/n A、C/n B、D/n C、E/n F、G。创建映射后,调用JSON序列化程序是否会将其转换为指定的JSON格式?@TeeJay是的,如果您已排序数据(根节点总是在其子节点之前提及),则不需要任何其他逻辑。许多库允许将JavaPOJO转换为JSON。
节点
类是一个经典的POJO。看看杰克逊或格森图书馆。此外,如果您需要顶部的“hierarchy”属性,则应将返回的列表包装到其他对象中(使用属性
hierarchy
的类,或使用键为“hierarchy”的单个条目进行映射)
String csv = ""
    + "Fruit, Mango\n"
    + "Fruit, Apple\n"
    + "Car, Audi\n"
    + "Apple, Red\n"
    + "Color, Brown\n"
    + "Red, Fire\n";
Set<String> topLevels = new LinkedHashSet<>();
Set<String> notTopLevels = new LinkedHashSet<>();
Map<String, Map<String, Object>> 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<String, Object> value = labels.computeIfAbsent(
            fields[1], k -> new LinkedHashMap<String, Object>());
        labels.computeIfAbsent(
            fields[0], k -> new LinkedHashMap<String, Object>())
            .put(fields[1], value);
        topLevels.add(fields[0]);
        notTopLevels.add(fields[1]);
    }
}
Map<String, Object> 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={}}}