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

时间:2012-05-18 21:50:56

标签: java json tree

假设在这种情况下我有这样的表/列表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背景。

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

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

    parentId parText answerId

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

  • 1 1 1气体
  • 1 2 2 Compact
  • 1 3 3卡罗拉
  • 2 1 1气体
  • 2 2 2 Compact
  • 2 3 4凯美瑞
  • ...

    然后我需要使它成为一个树(嵌套输出,如JSON显示父/子 - 就像你创建一个文件系统目录一样)

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

    输出有点偏,我正在寻找这样的东西。如果没有孩子那么没有孩子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"}]}
    
  • 1 个答案:

    答案 0 :(得分:2)

    您应该在所需的结构中创建用于建模数据的类。您基本上希望从某些基于行的数据构建层次结构,这非常类似于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<String> path = new ArrayList<String>();
                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<TreeItem>{
    
            private Map<String, TreeItem> children;     
            private String name;
    
            public TreeItem() {
                children = new HashMap<String, TreeItem>();
            }
    
            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<TreeItem> 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<String> path)
            {
                addData(this, path);
            }
    
            private void addData(TreeItem parent, List<String> 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<String> path)
            {
                return (Group) getData(this, path);
            }
    
            private TreeItem getData(TreeItem parent, List<String> 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<String, Object> 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<String, Object>();
            }       
        }
    }
    

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

    如果您不仅是Java新手,而是Object Orientated Programming,那么您应该阅读这个主题。我在这里写的代码并不完美,我已经可以看到它可以改进的方法了。学习编写高质量的面向对象的代码需要时间和练习。阅读Design PatternsCode Smells