英文:
Gson converts the HashMap<Integer> to HashMap<String> inside my Object
问题
我有一个对象,里面有一个映射(map):
MyDTO
HashMap<Integer>
现在,当我将我的 MyDTO 对象转换为 JSON(使用 Gson),然后再从 JSON 转换回 MyDTO 对象时,我得到的是 HashMap<String>
。
我是这样从 JSON 转回对象的:
MyDTO dto = gson.fromJson(json, MyDTO.class);
如何强制它将 DTO 内部的 Map 转换/保持为 Map<Integer>
,而不是 Map<String>
?
这是我的对象:
public class MultiSeriesTimebasedChartDTO implements Serializable
{
LinkedHashMap<String, ArrayList<Number>> data;
}
以下是我如何将 JSON 转回对象的代码:
multiSeriesTimebasedChartDTO = gson.fromJson(json, MultiSeriesTimebasedChartDTO.class);
这是结果(在截图中显示),本来是数字,现在变成了字符串。我需要它们作为数字返回。
因此,希望找到一个干净的方法来解决这个问题。
我当然可以迭代它,将每个数字从字符串更改回数字,并进行替换... 但我在想可能有其他更好的方法来做这件事。
英文:
I have an object which has a map inside it:
MyDTO
HashMap<Integer>
Now when I convert my MyDTO to JSON (with Gson), and then back from JSON to MyDTO what I get is HashMap<String>
.
I convert from JSON back to object like this:
MyDTO dto = gson.fromJson(json, MyDTO.class);
How can I force it to convert/keep the Map inside the DTO as Map<Integer>
and NOT as Map<String>
?
Here is my Object:
public class MultiSeriesTimebasedChartDTO implements Serializable
{
LinkedHashMap<String, ArrayList<Number>> data;
}
Here's how I convert my JSON back to object:
multiSeriesTimebasedChartDTO = gson.fromJson(json, MultiSeriesTimebasedChartDTO.class);
And here is the result (in screenshot), which were Numbers but now are Strings. I needed them back as Numbers.
So looking for a clean approach for this.
I can definitely iterate over it, change every number from string back to number, and replace it... But I was thinking may be there is some other better way of oing it.
答案1
得分: 1
这些值在解析JSON后仍然是java.lang.Number
。然而,由于您的字段具有类型<code>LinkedHashMap<String,ArrayList<<b>Number</b>>></code>,Gson会使用其内部类型LazilyParsedNumber
,因为它无法确定您希望将Number
解析为哪种特定类型。LazilyParsedNumber充当JSON字符串表示的包装器,因此您可以调用相应的Number
方法来解析该值。
如果您仅想检索其intValue()
,doubleValue()
等值,LazilyParsedNumber就足够了,但如果想将其与其他数字进行比较,则不行,因为LazilyParsedNumber只等于自身。
由于您的问题提到Map包含Integer
值,最简单的解决方案是更改DTO字段的类型:
<pre>
LinkedHashMap<String,ArrayList<<b>Integer</b>>>
</pre>
这样,Gson就知道您想要的确切数字类型,并且可以正确地将JSON数字反序列化为Integers。
英文:
The values are still java.lang.Number
s after the JSON is parsed. However, because your field has the type <code>LinkedHashMap<String, ArrayList<<b>Number</b>>></code>, Gson uses its internal type LazilyParsedNumber
because it cannot know as which specific type you want the Number
s to be parsed. LazilyParsedNumber acts as a wrapper for the JSON string representation so you can call the respective Number
method to parse the value.
LazilyParsedNumber should suffice if you are only retrieving its intValue()
, doubleValue()
..., but if want to compare it with other Numbers it wont work since LazilyParsedNumber is only equal to itself.
Since your question mentions that the Map contains Integer
values, the easiest solution would be to change the type of the DTO field:
<pre>
LinkedHashMap<String, ArrayList<<b>Integer</b>>>
</pre>
This way Gson knows the exact number type you want and can properly deserialize the JSON numbers as Integers.
答案2
得分: 0
你没有任何所谓的"HashMap<Integer>
",无论那是什么,你有ArrayList<Number>
,这是GSON需要准备的:
public class MultiSeriesTimebasedChartDTO implements Serializable{
LinkedHashMap<String, ArrayList<Number>> data;
^^^^^^^^^^^^^^^^^
}
而且,你所抱怨的并不是String
,它们是LazilyParsedNumber
,
虽然它实际上将值存储为字符串,但这个类确实是一个Number
。你不必担心它的私有成员变量。
public final class LazilyParsedNumber extends Number { // <= extends Number
private final String value; // <= 这是你在调试器中看到的
但这只是关于现有内容的解释。如果你想让GSON为你生成一个Integer
列表,你只需要这样写:
public class MultiSeriesTimebasedChartDTO implements Serializable{
LinkedHashMap<String, ArrayList<Integer>> data;
}
记住,GSON只能分析类的声明,它无法猜测你是否稍后确保所有这些泛型数字都是整数。
英文:
You have no "HashMap<Integer>
" whatever that could be, you have ArrayList<Number>
, and that is what GSON has to prepare for:
> public class MultiSeriesTimebasedChartDTO implements Serializable{
> LinkedHashMap<String, ArrayList<Number>> data;
> ^^^^^^^^^^^^^^^^^
> }
Also, you don't have String
s what you complain about, those are LazilyParsedNumber
s,
>
And while it really stores the value as a string, that class indeed is a Number
. You don't have to worry about its private member variables.
> public final class LazilyParsedNumber extends Number { // <= extends Number
> private final String value; // <= this is what you see in the debugger
But that is just the explanation about what's there now. If you want GSON to produce you a list of Integer
s, you should simply write that:
public class MultiSeriesTimebasedChartDTO implements Serializable{
LinkedHashMap<String, ArrayList<Integer>> data;
}
remember that GSON can only analyse the declaration of the class, it can't guess if you later ensure that all those generic numbers are integers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论