将数组转换为分层JSONArray

时间:2018-03-12 14:21:29

标签: java arrays json hierarchical

假设我有一个表示包结构的字符串数组。 它看起来像这样:

Array {
  "com.project.server",
  "com.project.client",
  "com.project.client.util",
  ...
}

它没有定义一个包可以包含多少级别。

现在我想将其转换为分层JSON-Object。 这应该是这样的:

{
    "name": "com",
    "children": [
        {
            "name": "project",
            "children": [
                {
                    "name": "server"
                }, 
                {
                    "name": "client",
                    "children": [
                        {
                            "name": "util"
                        }
                    ]
                }
            ]
        }
    ]
}

我希望你能理解我想要的东西。

说实话,我无可救药地被质疑......

你能帮帮我吗? 谢谢,抱歉可能会有糟糕的英语。

4 个答案:

答案 0 :(得分:0)

你去吧!

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

public class ParseTree {

    public PackageInfo getRoot(List<String> packages) throws JsonProcessingException {
        Map<String, PackageInfo> map = new HashMap<>();

        String root = null;
        for (String packageName : packages) {
            String[] split = packageName.split("\\.");
            for (int i = 0; i < split.length; i++) {
                String singlePackage = split[i];
                if (root == null) {
                    root = singlePackage;
                }
                map.computeIfAbsent(singlePackage, PackageInfo::new);
                if (i - 1 >= 0) {
                    PackageInfo currentPackage = map.get(singlePackage);
                    map.get(split[i - 1]).getChildren().add(currentPackage);
                }
            }
        }

        return map.get(root);
    }

    public static void main(String[] args) throws JsonProcessingException {
        List<String> packages = Arrays.asList("com.project.server",
            "com.project.client",
            "com.project.client.util", "com.project.client.util.some");

        ParseTree parseTree = new ParseTree();
        PackageInfo root = parseTree.getRoot(packages);
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(root));
    }
}

class PackageInfo {

    private String name;
    private Set<PackageInfo> children;

    public PackageInfo(String name) {
        this.name = name;
        children = new HashSet<>();
    }

    public Set<PackageInfo> getChildren() {
        return children;
    }

    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        PackageInfo that = (PackageInfo) o;
        return Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name);
    }

    @Override
    public String toString() {
        return "PackageInfo{" +
            "name='" + name + '\'' +
            ", children=" + children +
            '}';
    }
}

它会输出

{
   "name":"com",
   "children":[
      {
         "name":"project",
         "children":[
            {
               "name":"server",
               "children":[

               ]
            },
            {
               "name":"client",
               "children":[
                  {
                     "name":"util",
                     "children":[
                        {
                           "name":"some",
                           "children":[

                           ]
                        }
                     ]
                  }
               ]
            }
         ]
      }
   ]
}

答案 1 :(得分:0)

听起来你需要Java中的Tree结构。已经讨论了多个解决方案here

然后,您可以以标准方式转换输入/输出JSON。

答案 2 :(得分:0)

对于包的特定问题,请考虑使用类似树的实现。您可以使树仅包含唯一节点。这样您就可以将数据格式化为正确的格式。 下面是一些关于如何创建树的伪代码:

class Tree
    Tree[] children
     String data;

现在要向此树添加内容,您只需像链接列表一样遍历它,这意味着您可以添加按数字访问子项的方法。此外,当您添加节点时,请确保它们是唯一的,方法是将它们与您添加它的级别上已存在的节点进行比较。因为你更专注于从树中实际转换成Json。

一种可能的算法是以递归方式遍历树并从中创建String,如下所示:

public String getJsonFormat(Tree root){
for(Tree child : root.getChildren())
    {
        return "{\n\"name\":\"" + child.data + "\",  \n\"children\":[\n" + getJsonFormat(child) + "\n}"
    }

现在,它为您提供了Json,您现在可以使用它。为了向树中添加内容,这里有一个关于如何操作的算法。

addStuffToTree(String packagePath)
    {
     array = packagePath.split("\\.");
     //We now know that the elements in the array, correspond to the level of the tree they are supposed to be in, therefore:
    Tree temp = root; //new Tree which is equal to your root
     if(temp.data != array[0])
    for( i=1; i < array.length; i++){
        for(Tree tree : temp.getChildren())
            if(tree.data == array[i])
                 {temp=tree;
                 i++;
                 // We will traverse the tree like this, avoiding duplicates
                  }
         temp.add(array[i])
         temp = newest child
          //This adds a node if it hasn't been there yet if there are more iterations, it will continue running under that node, if not it will exit the loop
    }

对不起,这不是很漂亮,在我的手机上制作。

答案 3 :(得分:0)

与其他解决方案没有什么不同,但自从我做到了,你就是

@Data
public class Node {
    String name;
    List<Node> children;
    public Node(String name) {
        this.name = name;
        children = new ArrayList<>();
    }
}

public static void main(String[] args) {
    List<String> a = Arrays.asList(
            "com.project.server",
            "com.project.client",
            "com.project.client.util"
        );
    List<Node> root = new ArrayList<>();
    for (String s: a) {
        List<String> packs = Arrays.asList(s.split("\\."));
        List<Node> current = root;
        for (String pack : packs) {
            Optional<Node> newCur = current.stream().filter(node -> node.name.equals(pack)).findFirst();
            if (newCur.isPresent()) {
                current = newCur.get().children;
            } else {
                Node newNode = new Node(pack); 
                current.add(newNode);
                current = newNode.children;
            }
        }
    }
    System.out.println(root);
}

json转换应该是非常标准的

使用生成toString的lomboks输出:

[Node(name=com, children=[Node(name=project, children=[Node(name=server, children=[]), Node(name=client, children=[Node(name=util, children=[])])])])]