3

假设在这种情况下我有这样的表/列表 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 来解析并写入 API。另外一点,每个 id 都有与之关联的其他数据,这些数据必须包含在 json 输出中。例如,而不是 {groupid:1} 需要这个 {groupid:1, text=toyota}。

非常感谢任何帮助,因为我来自 SAS 背景,所以我对 java 还很陌生。

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

  • 丰田、汽油、紧凑型、凯美瑞
  • 丰田、混合动力、紧凑型、普锐斯
  • 本田, 汽油, 紧凑型, 思域
  • 如果需要,我可以将数据重新格式化为两个表

    parentId parText answerId

  • 1 丰田 1
  • 1 丰田 2
  • 1 丰田 3
  • 2 本田 4
  • answerId 级别 answerTextid answerText

  • 1 1 1 气体
  • 1 2 2 紧凑型
  • 1 3 3 卡罗拉
  • 2 1 1 气体
  • 2 2 2 紧凑型
  • 2 3 4 凯美瑞
  • …</p>

    然后我需要把它做成一棵树(嵌套输出像 JSON 显示父/子 - 就像你正在创建一个文件系统目录一样)

    我想做的另一件事是每辆车都有里程作为变量({answerid3:4,text = Corolla,mileage = 38}。但如果我遍历树,给分支的平均里程。就像说在丰田、Gas、Compact 分公司,行驶里程为 avg(凯美瑞、卡罗拉)

    输出有点偏,我正在寻找这样的东西。如果没有孩子则没有孩子数组列表,并且属性是一个对象的一部分(哈希图)

    {"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"}]}
    
  • 4

    1 回答 1

    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 值的平均值作为读者的练习(我只有这么多时间......)。这个解决方案非常通用 - 您可能需要更具体的子类来更好地描述您的数据模型(如制造商、类型、模型),因为您将能够从它们身上挂起更多有用的方法(如计算子字段的平均值objects) ,并且您不必将属性作为Objects 的集合来处理,但是您会得到更复杂的代码来从列表中初始化数据结构。注意 - 这不是生产就绪代码,我只是提供了它作为示例,说明您可以如何使用 Java 对数据进行建模。

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

    于 2012-05-18T22:25:56.467 回答