【问题标题】:Flattening a JSONObject in Java - Recursion causing StackOverflowError在 Java 中展平 JSONObject - 递归导致 StackOverflowError
【发布时间】:2014-04-04 17:54:35
【问题描述】:

我一直在编写一种方法来“扁平化”Java 中的 codehaus JSONObject。不幸的是,我在通过对象嵌套的递归中看到了 StackOverflowError,但我发现它很难调试。这是我看到的错误:

Exception in thread "main" java.lang.StackOverflowError
    at java.util.LinkedHashMap$LinkedHashIterator.<init>(LinkedHashMap.java:345)
    at java.util.LinkedHashMap$LinkedHashIterator.<init>(LinkedHashMap.java:345)
    at java.util.LinkedHashMap$KeyIterator.<init>(LinkedHashMap.java:383)
    at java.util.LinkedHashMap$KeyIterator.<init>(LinkedHashMap.java:383)
    at java.util.LinkedHashMap.newKeyIterator(LinkedHashMap.java:396)
    at java.util.HashMap$KeySet.iterator(HashMap.java:874)
    at org.codehaus.jettison.json.JSONObject.keys(JSONObject.java:533)
    at org.codehaus.jettison.json.JSONObject.toString(JSONObject.java:1079)
    at org.codehaus.jettison.json.JSONObject.valueToString(JSONObject.java:1210)

我使用Iterator 循环键,并使用hasNext()next() 确保我应该只能访问特定对象键。

我开始用一个简单的 JSONObject 进行测试:

JSONObject json = new JSONObject("outer":{"field1":"value","inner":{"field2":12345,"field3":"example@example.com"}});

/*
"outer":{
    "field1":"value",
    "inner":{
        "field2":12345,
        "field3":"example@example.com"
    }
}
*/

这应该会产生一个包含fields1|2|3 的嵌套。

这是我目前的代码:

private static JSONObject flatten(JSONObject object, JSONObject flattened){
    if(flattened == null){
        flattened = new JSONObject();
    }
    Iterator<?> keys = object.keys();
    while(keys.hasNext()){
        String key = (String)keys.next();
        try {
            if(object.get(key) instanceof JSONObject){
                flattened.put(key, flatten(object.getJSONObject(key), flattened));
            } else {
                flattened.put(key, object.get(key));
            }
        } catch(JSONException e){
            System.out.println(e);
        }
    }
    return flattened;
}

我已经对此进行了一段时间的调试,但还没有取得任何进展——因此,我将不胜感激。提前感谢您的帮助 - 如果需要更多信息,请发表评论。

【问题讨论】:

  • 尝试用flatten(object.getJSONObject(key), flattened); 替换flattened.put(key, flatten(object.getJSONObject(key), flattened));,它给了我{"field1":"value","field2":12345,"field3":"example@example.com"},我认为这就是你想要的
  • @RC。哦,呃,完全有效 - 不敢相信我错过了。你想留下它作为答案吗?

标签: java json object jackson jsonobject


【解决方案1】:

替换

flattened.put(key, flatten(object.getJSONObject(key), flattened));

通过

flatten(object.getJSONObject(key), flattened);

这里给了我{"field1":"value","field2":12345,"field3":"example@example.com"},我想这就是你想要的

【讨论】:

    【解决方案2】:

    请注意,当您递归调用函数时,您会将“扁平化”对象传递给函数,然后它会将其返回给您,然后您将其添加到“扁平化”对象中。因此,您将对象添加到自身,创建循环引用

    当您进行递归调用时,不要将结果添加回对象中。做吧:

    flatten(object.getJSONObject(key), flattened);
    

    【讨论】:

    • 很好的解释,当你接受它时很明显(完全忘记传递flattened。我赞成你的答案,但是RC是第一位的,这就是他有明显答案的原因。谢谢!跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 2014-11-09
    • 2012-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多