java json org.json

¿Cómo puedo clonar un org.json.JSONObject en Java?



(5)

¿Hay alguna forma de clonar una instancia de org.json.JSONObject sin tener que clasificarlo y volver a analizar el resultado?

Una copia superficial sería aceptable.


Causa $JSONObject.getNames(original) no accesible en Android, puede hacerlo con:

public JSONObject shallowCopy(JSONObject original) { JSONObject copy = new JSONObject(); for ( Iterator<String> iterator = original.keys(); iterator.hasNext(); ) { String key = iterator.next(); JSONObject value = original.optJSONObject(key); try { copy.put(key, value); } catch ( JSONException e ) { //TODO process exception } } return copy; }

Pero recuerda que no es copia profunda.


En caso de que alguien venga aquí buscando un clon profundo para org.google.gson, ya que no exponen su método deepClone (), esto es lo que se me ocurrió ...

public static JsonElement deepClone(JsonElement el){ if (el.isJsonPrimitive() || el.isJsonNull()) return el; if (el.isJsonArray()) { JsonArray array = new JsonArray(); for(JsonElement arrayEl: el.getAsJsonArray()) array.add(deepClone(arrayEl)); return array; } if(el.isJsonObject()) { JsonObject obj = new JsonObject(); for (Map.Entry<String, JsonElement> entry : el.getAsJsonObject().entrySet()) { obj.add(entry.getKey(), deepClone(entry.getValue())); } return obj; } throw new IllegalArgumentException("JsonElement type " + el.getClass().getName()); }

Y aquí hay algunos métodos para combinar dos JsonObject

public static JsonObject merge(String overrideJson, JsonObject defaultObj) { return mergeInto((JsonObject)new JsonParser().parse(overrideJson), defaultObj); } public static JsonObject merge(JsonObject overrideObj, JsonObject defaultObj) { return mergeOverride((JsonObject)deepClone(defaultObj), overrideObj); } public static JsonObject mergeOverride(JsonObject targetObj, JsonObject overrideObj) { for (Map.Entry<String, JsonElement> entry : overrideObj.entrySet()) targetObj.add(entry.getKey(), deepClone(entry.getValue())); return targetObj; } public static JsonObject mergeInto(JsonObject targetObj, JsonObject defaultObj) { for (Map.Entry<String, JsonElement> entry : defaultObj.entrySet()) { if (targetObj.has(entry.getKey()) == false) targetObj.add(entry.getKey(), deepClone(entry.getValue())); } return targetObj; }


La forma más fácil de hacerlo.

JSONObject clone = new JSONObject(original.toString());


No se pudo encontrar un método de clonación profunda existente para com.google.gwt.json.client.JSONObject pero la implementación debe ser de algunas líneas de código, algo como:

public static JSONValue deepClone(JSONValue jsonValue){ JSONString string = jsonValue.isString(); if (string != null){return new JSONString(string.stringValue());} JSONBoolean aBoolean = jsonValue.isBoolean(); if (aBoolean != null){return JSONBoolean.getInstance(aBoolean.booleanValue());} JSONNull aNull = jsonValue.isNull(); if (aNull != null){return JSONNull.getInstance();} JSONNumber number = jsonValue.isNumber(); if (number!=null){return new JSONNumber(number.doubleValue());} JSONObject jsonObject = jsonValue.isObject(); if (jsonObject!=null){ JSONObject clonedObject = new JSONObject(); for (String key : jsonObject.keySet()){ clonedObject.put(key, deepClone(jsonObject.get(key))); } return clonedObject; } JSONArray array = jsonValue.isArray(); if (array != null){ JSONArray clonedArray = new JSONArray(); for (int i=0 ; i < array.size() ; ++i){ clonedArray.set(i, deepClone(array.get(i))); } return clonedArray; } throw new IllegalStateException(); }

* Nota: * No lo he probado todavía!