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}
                        ]
                }

               ]      
        }

そうするためのコード/ステップは何でしょうか。私はたくさんのタグを調べましたが、ほとんどの人は出力を出力しており、APIへの書き込みを解析するためにGSONのハッシュマップ/ArrayListを再帰的に作成していません。各IDには、json出力に含める必要のある他のデータが関連付けられているもう1つのポイントがあります。たとえば、{groupid:1}の代わりにこの{groupid:1、text=toyota}が必要になります。

私はSASのバックグラウンドを持っているので、Javaはかなり新しいので、どんな助けでも大歓迎です。

私はこのようなデータを取得します(リストの単なるマトリックス)トヨタ、ガス、コンパクト、カローラ

  • トヨタ、ガス、コンパクト、カムリ
  • トヨタ、ハイブリッド、コンパクト、プリウス
  • ホンダ、ガス、コンパクト、シビック
  • 必要に応じて、データを2つのテーブルに再フォーマットできます

    parentId parText answerId

  • 1トヨタ1
  • 1トヨタ2
  • 1トヨタ3
  • 2ホンダ4
  • answerIdレベルanswerTextidanswerText

  • 111ガス
  • 122コンパクト
  • 133カローラ
  • 211ガス
  • 222コンパクト
  • 234カムリ
  • …</p>

    次に、それをツリーにする必要があります(JSONが親/子で表示するようなネストされた出力-ファイルシステムディレクトリを作成した場合と同じように)

    私がやりたいもう1つの考えは、各車がvarialbeとしてマイレージを持っていることです({answerid3:4、text = Corolla、mileage = 38}。また、ツリーをトラバースする場合は、ブランチの平均マイルを与えます。たとえば、トヨタ、ガス、コンパクトの支店では、走行距離は平均になります(カムリ、カローラ)

    出力が少しずれているので、このようなものを探しています。子がない場合は子の配列リストはなく、属性は1つのオブジェクトの一部です(ハッシュマップ)

    {"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値の平均化を省略しましたが、これはこれまでに述べた要件のほとんどを満たしていると思います(時間はあまりありません...)。このソリューションは非常に一般的です。データモデル(Manufacturer、Type、Modelなど)をより適切に説明するより具体的なサブクラスが必要になる場合があります。これにより、より便利なメソッド(子のフィールドの平均の計算など)をハングアップできるようになります。オブジェクト)、プロパティをsのコレクションとして扱う必要はありませんがObject、リストからデータ構造を初期化するより複雑なコードを取得します。注-これは本番環境に対応したコードではありません。Javaでデータをモデル化する方法の例として提供しました。

    Javaだけでなく、オブジェクト指向プログラミングに慣れていない場合は、このテーマについてよく読んでください。私がここに書いたコードは完璧ではありません、私はそれが改善されることができる方法をすでに見ることができます。質の高いオブジェクト指向コードの記述方法を学ぶには、時間と練習が必要です。デザインパターンコードの臭いを読んでください。

    于 2012-05-18T22:25:56.467 に答える