我收到了一个基于SON格式的响应,其中n元树的PRENER穿越以JSONArray给出.我需要将其转换为树 struct 并发送回来作为响应.

给出回应

{
  "ControllingArea" : "TZUS",
  "TopNodes" : false,
  "Language" : "EN",
  "TONODES" : [
    {
      "Groupname" : "INC",
      "Hierlevel" : 0,
      "Valcount" : 0,
      "Descript" : "INC"
    },
    {
      "Groupname" : "INC-BBSR",
      "Hierlevel" : 1,
      "Valcount" : 0,
      "Descript" : "INC1"
    },
    {
      "Groupname" : "INC-STPI",
      "Hierlevel" : 2,
      "Valcount" : 0,
      "Descript" : "INC2"
    },
    {
      "Groupname" : "INC-FORT",
      "Hierlevel" : 2,
      "Valcount" : 0,
      "Descript" : "INC3"
    },
    {
      "Groupname" : "INC-BBL",
      "Hierlevel" : 1,
      "Valcount" : 0,
      "Descript" : "INC4"
    },
    {
      "Groupname" : "INC-PUNE",
      "Hierlevel" : 1,
      "Valcount" : 0,
      "Descript" : "INC5"
    }
  ],
  "TOVALUE" : [
    {
      "Valfrom" : "",
      "Valto" : ""
    }
  ]
}

这里的TONODES代表树上的Preorder穿越,也在对象中给出了它所属的级别.

树应该看起来像(UI视图).

tree image

我想发送的回复应该是:

{
    "INC": {
        "Groupname": "INC",
        "Hierlevel": 0,
        "Valcount": 0,
        "Descript": "INC",
        "INC-BBSR": {
            "Groupname": "INC-BBSR",
            "Hierlevel": 1,
            "Valcount": 0,
            "Descript": "INC1",
            "INC-STPI": {
                "Groupname": "INC-STPI",
                "Hierlevel": 2,
                "Valcount": 0,
                "Descript": "INC2"
            },
            "INC-FORT": {
                "Groupname": "INC-FORT",
                "Hierlevel": 2,
                "Valcount": 0,
                "Descript": "INC3"
            }
        },
        "INC-BBL": {
            "Groupname": "INC-BBL",
            "Hierlevel": 1,
            "Valcount": 0,
            "Descript": "INC4"
        },
        "INC-PUNE": {
            "Groupname": "INC-PUNE",
            "Hierlevel": 1,
            "Valcount": 0,
            "Descript": "INC5"
        }
    }
}

我try 在网上搜索了很多生成N-Ary树的方法,但没有得到任何满意的结果.因为解决方案说,如果你知道n,u就能够做出树,但我不知道这里的n,因为它可以是随机的.

我还try 在对象的更高层次 struct 即将到来时使用堆栈将 node 插入到其中,并在对象的较低层次 struct 即将到来时弹出.

@Override
    public ResponseDTO getTreeStructure(JSONObject sapResponse) {

        JSONObject response = new JSONObject();

        Stack<JSONObject> treeStack = new Stack<>();

        JSONArray iteratingArray = sapResponse.getJSONArray("TONODES");

        for(int i = 0 ; i < iteratingArray.length(); i++){
            JSONObject tempObject= iteratingArray.getJSONObject(i);

            if(treeStack.empty()) {
                treeStack.push(tempObject);
                response.put(tempObject.getString("Groupname"), tempObject);
            }else if(treeStack.peek().getInt("Hierlevel") < tempObject.getInt("Hierlevel")){
                response.getJSONObject(treeStack.peek().getString("Groupname")).put(tempObject.getString("Groupname"), tempObject);
                treeStack.push(tempObject);
            }else if(treeStack.peek().getInt("Hierlevel") >= tempObject.getInt("Hierlevel")){
                while(!treeStack.empty() && treeStack.peek().getInt("Hierlevel") >= tempObject.getInt("Hierlevel")){
                    treeStack.pop();
                }
                response.getJSONObject(treeStack.peek().getString("Groupname")).put(tempObject.getString("Groupname"), tempObject);
                treeStack.push(tempObject);
            }
        }

        return new ResponseDTO(200, "ok", response);

        //return null;
    }

问题是我无法让之前的对象推入响应.我无法追踪父 node 来获取并到达当前 node 进行推送.

0(N0) -> 1(N1) -> 2(N2)

response.getJSONObject(N0).getJSONObjectI(N1).put(N2.getString("Groupname"), N2);

但相反,在我的方法中,我得到了

response.getJSONObject(N1).put(N2)

I can get the node 1 from the top of the stack, but I cannot track down the parent 0th node to push the 2nd object under 1st.

如果以某种方式可以按照层次 struct 获得之前的 node ,我就能够创建树.

请更正我的代码或告诉我解决这个问题的更好方法.

推荐答案

请更正我的代码或告诉我解决这个问题的更好方法.

Stack方法对于您需要做的事情来说绝对是很好的,特别是如果您考虑到给定Json中的 node 始终按顺序列出(每个 node 之前总是有其父 node 或sibling node ).

代码的唯一问题在于位response.getJSONObject(treeStack.peek().getString("Groupname")).在这里,您正在try 从正在构建的Json中检索父 node ,而不是Stack.您的Stack在顶部已经有您需要的父 node ,只需使用treeStack.peek()即可.此外,getJSONObject查找由给定名称only within node 标识的属性.它不会进一步搜索,而是按其嵌套的JSONObject个属性递减.

这是您代码的调整版本:

public ResponseDTO getTreeStructure(JSONObject sapResponse) {
    JSONObject response = new JSONObject();
    Stack<JSONObject> treeStack = new Stack<>();
    JSONArray iteratingArray = sapResponse.getJSONArray("TONODES");

    for (int i = 0; i < iteratingArray.length(); i++) {
        JSONObject tempObject = iteratingArray.getJSONObject(i);

        if (treeStack.empty()) {
            //When the tree is empty the current node is put as the root
            response.put(tempObject.getString("Groupname"), tempObject);
            treeStack.push(tempObject);

            //Checking if the current node is a child of the previous node (the one at the top of the stack)
        } else if (treeStack.peek().getInt("Hierlevel") < tempObject.getInt("Hierlevel")) {

            // Retrieving the parent node from the stack with 'treeStack.peek()'
            // instead of retrieving it from the json (response) with 'response.getJSONObject(treeStack.peek().getString("Groupname"))'
            //
            // The previous writing couldn't work, because getJSONObject() searches for an attribute identified by
            // the given name only within the current node, it does NOT further the search in its JSONObject attributes.
            // Furthermore, retrieving the parent node with getJSONObject() is redundant as the parent node is already
            // at the top of the stack.
            //
            //Once the parent node is retrieved from the stack, the current node is added to it
            treeStack.peek().put(tempObject.getString("Groupname"), tempObject);
            treeStack.push(tempObject);
        } else if (treeStack.peek().getInt("Hierlevel") >= tempObject.getInt("Hierlevel")) {

            //Getting rid of the nodes with the same level (the siblings)
            while (!treeStack.empty() && treeStack.peek().getInt("Hierlevel") >= tempObject.getInt("Hierlevel")) {
                treeStack.pop();
            }

            //Adding the current node to the parent node
            treeStack.peek().put(tempObject.getString("Groupname"), tempObject);
            treeStack.push(tempObject);
        }
    }

    return new ResponseDTO(200, "ok", response);
}

这里还有OneCompiler处的实时演示,您可以在其中测试代码.

Java相关问答推荐

我可以从Java模块中排除maven资源文件夹吗?

OpenJDK、4K显示和文本质量

填写文本字段后锁定PDF

Android Studio—java—在onBindViewHolder中,将断点和空白添加到BackclerView中

使用java访问具体子类特定方法的最佳方法是什么?

如何以干净的方式访问深度嵌套的对象S属性?

如何使用Maven和Spring Boot将构建时初始化、跟踪类初始化正确传递到本机编译

Com.example.service.QuestionService中的构造函数的参数0需要找不到的类型为';com.example.Dao.QuestionDao;的Bean

Jenv-相同的Java版本,但带有前缀

Spring-Boot Kafka应用程序到GraalVM本机映像-找不到org.apache.kafka.streams.processor.internals.DefaultKafkaClientSupplier

如何在不删除Java中已有内容的情况下覆盖文件内容?

在Java 15应用程序中运行Java脚本和Python代码

如何在我的世界中为互动增加冷却时间?

如何在Jooq中获取临时表列引用?

Java创建带有扩展通配符的抽象处理器

项目react 堆中doOnComplete()和Subscribe()的第三个参数之间的差异

为什么mvn编译生命周期阶段不只是编译已更改的java文件?

如何在Selenium上继续使用最新的WebDriver版本

在输入端没有可行的替代方案'; Select *';

如何显示新布局