I've been writing a method to "flatten" a codehaus JSONObject
in Java. Unfortunately, I'm seeing a StackOverflowError in the recursion through the object nests, but I'm finding it difficult to debug. Here is the error I'm seeing:
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)
I'm using Iterator
to loop the keys, and using hasNext()
and next()
to ensure that I should only be able to access specific object keys.
I started testing with a simple JSONObject of:
JSONObject json = new JSONObject("outer":{"field1":"value","inner":{"field2":12345,"field3":"[email protected]"}});
/*
"outer":{
"field1":"value",
"inner":{
"field2":12345,
"field3":"[email protected]"
}
}
*/
This should result in a single nest containing fields1|2|3
.
Here is the code I have so far:
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;
}
I have been debugging this for a while now, but haven't been able to make any headway - so I'd appreciate any pointers with this. Thanks in advance for any help - if any more info is needed, just leave a comment.
Replace
flattened.put(key, flatten(object.getJSONObject(key), flattened));
by
flatten(object.getJSONObject(key), flattened);
Here it gives me {"field1":"value","field2":12345,"field3":"[email protected]"}
and I think that's what you want
Notice that when you call the function recursively, you pass the "flattened" object into the function, and then it returns it back to you, which you then add to "flattened". Thus you are adding the object to itself, creating a circular reference
When you do the recursive call, don't add the result back into the object. Just do:
flatten(object.getJSONObject(key), flattened);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With