使用列表/表中的json创建树

假设在这种情况下我有这样的表/列表n = 3,但是n可以是无限制的。

groupid answerid1 answerid2 answerid(n) 1 3 6 8 1 3 6 9 1 4 7 2 5 

我想用java创建这样的父/子树json输出。(我一直在使用GSON)

  { data: [ { groupid: 1, children: [ { answerid1: 1, children: [ { answerid2:3, children: [ { answerid3:6, children: [ {answerid4: 8}, {answerid4: 9} ] } }, { answerid2: 4, children: [ {answerid3:7} ] } ] }, { groupid1: 2, children: [ { answerid2: 5} ] } ] } 

这样做的代码/步骤是什么? 我查看了很多标签,但大多数人都在打印输出,而不是递归地为GSON构建一个hashmap / ArrayList来解析adn写入API。 另一点每个id都有与之关联的其他数据,这些数据必须包含在json输出中。 例如,而不是{groupid:1}需要这个{groupid:1,text = toyota}。

任何帮助都非常感谢,因为我来自SAS,因为我来自SAS背景。

我得到这样的数据(只是一个列表矩阵)丰田,气体,紧凑,卡罗拉

  • 丰田,天然气,紧凑型,凯美瑞
  • 丰田,混合动力,紧凑型,普锐斯
  • 本田,天然气,紧凑型,思域
  • 如果需要,我可以将数据重新编入两个表格

    parentId parText answerId

  • 1丰田1
  • 1丰田2
  • 1丰田3
  • 2本田4
  • answerId level answerTextid answerText

  • 1 1 1气
  • 1 2 2紧凑型
  • 1 3 3卡罗拉
  • 2 1 1气
  • 2 2 2紧凑型
  • 2 3 4凯美瑞
  • 然后我需要使它成为一个树(嵌套输出,如JSON显示与父/子 – 就像你创建一个文件系统目录)

    另一个我想做的是每辆车都有里程作为变种({answerid3:4,text =花冠,里程= 38}。但如果我遍历树,给分支平均一英里。就像说在分公司丰田,燃气,紧凑的里程将是平均(凯美瑞,卡罗拉)

    输出有点偏,我正在寻找这样的东西。 如果没有孩子那么没有孩子arraylist,并且attrbutes是一个对象的一部分(hashmap)

     {"data":[{"id":1,"children": [{"id": 2,"children": [{"id": 3 ,"children": [{"id": 4,"name":"Prius"}],"name":"Compact"}],"name":"Hybrid"}, {"id":5,"children": [{"id":3,"children": [{"id":7,"MPG":38, "name":"Corolla"}, {"id":8,"MPG":28,"name":"Camry"}],"name":"Compact"}],"name":"Gas"}],"name":"Toyota"}, {"id":9, "children": [{"id":10,"children": [{"id":3 ,"children": [{"id":11 ,"name":"Civic"}],"name":"Compact"}],"name":"Gas"}],"name":"Honda"}]} 

    您应该在所需的结构中创建用于建模数据的类。 您基本上希望从某些基于行的数据构建层次结构,这非常类似于XML文档,这可能是一个合适的解决方案。 但是你让我迷上了,所以我玩了之前我所拥有的并想出了这个:

     public class Test { public static void main(String[] args) { // hierarchical data in a flattened list String[][] data = { {"Toyota", "Gas", "Compact", "Corolla"}, {"Toyota", "Gas", "Compact", "Camry"}, {"Toyota", "Hybrid", "Compact", "Prius"}, {"Honda", "Gas", "Compact", "Civic"} }; TreeManager treeManager = new TreeManager(); for(String[] row : data) { // build the path to our items in the tree List path = new ArrayList(); for(String item : row) { // add this item to our path path.add(item); // will add it unless an Item with this name already exists at this path treeManager.addData(treeManager, path); } } treeManager.getData(data[0]).putValue("MPG", 38); treeManager.getData(data[1]).putValue("MPG", 28); Gson gson = new Gson(); System.out.println(gson.toJson(treeManager)); } /** * This base class provides the hierarchical property of * an object that contains a Map of child objects of the same type. * It also has a field - Name * */ public static abstract class TreeItem implements Iterable{ private Map children; private String name; public TreeItem() { children = new HashMap(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public void addChild(String key, TreeItem data) { children.put(key, data); } public TreeItem getChild(String key) { return children.get(key); } public boolean hasChild(String key) { return children.containsKey(key); } @Override public Iterator iterator() { return children.values().iterator(); } } /** * This is our special case, root node. It is a TreeItem in itself * but contains methods for building and retrieving items from our tree * */ public static class TreeManager extends TreeItem { /** * Will add an Item to the tree at the specified path with the value * equal to the last item in the path, unless that Item already exists */ public void addData(List path) { addData(this, path); } private void addData(TreeItem parent, List path) { // if we're at the end of the path - create a node String data = path.get(0); if(path.size() == 1) { // unless there is already a node with this name if(!parent.hasChild(data)) { Group group = new Group(); group.setName(data); parent.addChild(data, group); } } else { // pass the tail of this path down to the next level in the hierarchy addData(parent.getChild(data), path.subList(1, path.size())); } } public Group getData(String[] path) { return (Group) getData(this, Arrays.asList(path)); } public Group getData(List path) { return (Group) getData(this, path); } private TreeItem getData(TreeItem parent, List path) { if(parent == null || path.size() == 0) { throw new IllegalArgumentException("Invalid path specified in getData, remainder: " + Arrays.toString(path.toArray())); } String data = path.get(0); if(path.size() == 1) { return parent.getChild(data); } else { // pass the tail of this path down to the next level in the hierarchy return getData(parent.getChild(data), path.subList(1, path.size())); } } } public static class Group extends TreeItem { private Map properties; public Object getValue(Object key) { return properties.get(key); } public Object putValue(String key, Object value) { return properties.put(key, value); } public Group () { super(); properties = new HashMap(); } } } 

    我认为这符合你到目前为止提到的大部分要求,虽然我把MPG值的平均值作为读者的练习(我只有这么多时间……)。 这个解决方案非常通用 – 您可能需要更具体的子类来更好地描述您的数据模型(如制造商,类型,模型),因为您可以将更多有用的方法挂起来(比如计算子项中的字段平均值)您不必将属性作为Object的集合来处理,但是您可以从列表中获得更复杂的代码来初始化您的数据结构。 注意 – 这不是生产就绪代码,我刚刚提供了它作为如何用Java建模数据的示例。

    如果您不熟悉Java而不是面向对象编程,那么您应该阅读这个主题。 我在这里写的代码并不完美,我已经可以看到它可以改进的方法了。 学习编写高质量的面向对象的代码需要时间和练习。 阅读设计模式和代码气味 。