java Gson JsonObject 复制值影响其他 JsonObject 实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29786197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Gson JsonObject copy value affected others JsonObject instance
提问by user3057361
I have weird problem with gson (my gson version is 2.3.1) I have JsonObject instance called jsonObject (JsonObject jsonObject) jsonObject has value, not empty And I create another one, JsonObject tempOject = jsonObject; So, when I try to remove element inside tempObject, lets say, tempObject.remove("children");
我有 gson 的奇怪问题(我的 gson 版本是 2.3.1)我有一个名为 jsonObject 的 JsonObject 实例(JsonObject jsonObject)jsonObject 有值,不为空 我创建了另一个,JsonObject tempOject = jsonObject; 因此,当我尝试删除 tempObject 中的元素时,可以说, tempObject.remove("children");
Then that code affected the jsonObject instance.
然后该代码影响了 jsonObject 实例。
Here is the code snippet :
这是代码片段:
jsonObject = element.getAsJsonObject();
JsonElement tempElement = element;
JsonObject tempObject = jsonObject;
String tempJson;
if(tempObject.has("children")){
tempObject.remove("children");
tempJson = tempObject.toString();
tempElement = new JsonParser().parse(tempJson);
}
if(nodes.isEmpty()){
elements = new ArrayList<>();
nodes.put(iterator, elements);
}
if(!nodes.containsKey(iterator)){
elements = new ArrayList<>();
nodes.put(iterator, elements);
}
nodes.get(iterator).add(tempElement);
if (jsonObject.has("children")){
tempNextJson = jsonObject.get("children").toString();
tempCurrJson = jsonObject.toString();
tempIterator++;
metaDataProcessor(tempNextJson, tempCurrJson, tempNextJson, tempIterator, maxLevel);
}
I have read the gson JsonObject class, it use deep copy method. That was not supposed to affected the reference since JsonObject using deep value copy, so the returned JsonObject object is the new one.
我已经阅读了 gson JsonObject 类,它使用深复制方法。这不应该影响引用,因为 JsonObject 使用深值复制,所以返回的 JsonObject 对象是新的。
But why this is happened?
但是为什么会这样呢?
Anyway...there is deepCopy method inside JsonObject class
无论如何...... JsonObject 类中有 deepCopy 方法
JsonObject deepCopy() {
JsonObject result = new JsonObject();
Iterator i$ = this.members.entrySet().iterator();
while(i$.hasNext()) {
Entry entry = (Entry)i$.next();
result.add((String)entry.getKey(), ((JsonElement)entry.getValue()).deepCopy());
}
return result;
}
But thats an abstract method from JsonElement class which implemented on JsonObject, and the attribute not set as public, so I cannot call that method. But I guess that method supposedly called directly when I do instance copy.
但那是在 JsonObject 上实现的 JsonElement 类的抽象方法,并且属性未设置为公共,因此我无法调用该方法。但我猜想在我进行实例复制时应该直接调用该方法。
How about that?
那个怎么样?
Thanks in advance
提前致谢
回答by Muhammad Alfaifi
This can be used to copy any object of any type! just have to use Gson.
这可用于复制任何类型的任何对象!只需要使用Gson。
public <T> T deepCopy(T object, Class<T> type) {
try {
Gson gson = new Gson();
return gson.fromJson(gson.toJson(object, type), type);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
in your case you can call it like:
在你的情况下,你可以这样称呼它:
JsonObject jsonObject = deepCopy(oldJsonObject, JsonObject.class);
回答by JaakkoK
Starting from version 2.8.2, deepCopy()
in Gson JsonElement
is public, so you can now use it to make a deep copy of your JSON object.
从版本 2.8.2 开始,deepCopy()
GsonJsonElement
是公开的,因此您现在可以使用它来制作 JSON 对象的深层副本。
回答by Andy Guibert
Setting tempObject = jsonObject
will not create a second object for you. All that does is create another reference to your original jsonObject.
设置tempObject = jsonObject
不会为您创建第二个对象。所做的只是创建对原始 jsonObject 的另一个引用。
What you want to do is something like:
你想要做的是:
JSONObject tempObject = new JSONObject(jsonObject.toString());
tempObject.remove("children");
This will create a newJsonObject which is a copy of the original json you had.
这将创建一个新的JsonObject,它是您拥有的原始 json 的副本。
If you can only use the GSON libraries, there is the JsonObject.deepyCopy() method. Which was added in r855: https://code.google.com/p/google-gson/source/detail?r=855
如果您只能使用 GSON 库,则可以使用 JsonObject.deepyCopy() 方法。这是在 r855 中添加的:https: //code.google.com/p/google-gson/source/detail?r =855
Using the deepCopy() method it would be
使用 deepCopy() 方法将是
JsonObject tempObject = jsonObject.deepCopy();
tempObject.remove("children");
回答by user3057361
I have found the simplest solution for this. Since the deepCopy() method from JsonObject seems didn't work, then I just to make some transformation from JsonObject value to string and then transform to JsonElement with JsonParser(). Then make some new JsonObject from our new JsonObject. It seems more simple instead of create some helper method which is needs to reimplement the deepCopy. If we reimplement the iteration must considered how deep the JsonObject is. Since JsonObject is hashmap (LinkedTreeMap), and the value is JsonElement, so it need to parse recursively through JsonElement.
我找到了最简单的解决方案。由于 JsonObject 的 deepCopy() 方法似乎不起作用,所以我只是将 JsonObject 值转换为字符串,然后使用 JsonParser() 转换为 JsonElement。然后从我们的新 JsonObject 中创建一些新的 JsonObject。看起来更简单,而不是创建一些需要重新实现 deepCopy 的辅助方法。如果我们重新实现迭代必须考虑 JsonObject 的深度。由于JsonObject是hashmap(LinkedTreeMap),值为JsonElement,所以需要通过JsonElement递归解析。
回答by mindas
Looks like Gson developers decided not to expose deepCopy()
. You could serialize your JsonElement
this into a string and back, however, I think it's far more efficient to implement deep cloning outside of JsonObject
instead. Here's my solution to this:
看起来 Gson 开发人员决定不公开deepCopy()
. 您可以将JsonElement
this序列化为一个字符串并返回,但是,我认为在外部实现深度克隆效率更高JsonObject
。这是我的解决方案:
@Nonnull
public static JsonObject deepCopy(@Nonnull JsonObject jsonObject) {
JsonObject result = new JsonObject();
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
result.add(entry.getKey(), deepCopy(entry.getValue()));
}
return result;
}
@Nonnull
public static JsonArray deepCopy(@Nonnull JsonArray jsonArray) {
JsonArray result = new JsonArray();
for (JsonElement e : jsonArray) {
result.add(deepCopy(e));
}
return result;
}
@Nonnull
public static JsonElement deepCopy(@Nonnull JsonElement jsonElement) {
if (jsonElement.isJsonPrimitive() || jsonElement.isJsonNull()) {
return jsonElement; // these are immutables anyway
} else if (jsonElement.isJsonObject()) {
return deepCopy(jsonElement.getAsJsonObject());
} else if (jsonElement.isJsonArray()) {
return deepCopy(jsonElement.getAsJsonArray());
} else {
throw new UnsupportedOperationException("Unsupported element: " + jsonElement);
}
}