在Java中展平JSONObject - 导致StackOverflowError的递归

时间:2014-04-04 17:54:35

标签: java json object jackson jsonobject

我一直在编写一种方法来“压扁”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;
}

我已经调试了一段时间了,但是还没有取得任何进展 - 所以我很感激任何指针。在此先感谢您的帮助 - 如果需要更多信息,请发表评论。

2 个答案:

答案 0 :(得分:3)

替换

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

通过

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

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

答案 1 :(得分:2)

请注意,当您以递归方式调用函数时,将“flattened”对象传递给函数,然后将其返回给您,然后将其添加到“flattened”。因此,您将对象添加到自身,创建循环引用

执行递归调用时,请勿将结果添加回对象。只是做:

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