Gson将HashMap<Integer>转换为对象内的HashMap<String>。

huangapple go评论72阅读模式
英文:

Gson converts the HashMap<Integer> to HashMap<String> inside my Object

问题

我有一个对象,里面有一个映射(map):

MyDTO 
   HashMap&lt;Integer&gt; 

现在,当我将我的 MyDTO 对象转换为 JSON(使用 Gson),然后再从 JSON 转换回 MyDTO 对象时,我得到的是 HashMap&lt;String&gt;

我是这样从 JSON 转回对象的:

MyDTO dto = gson.fromJson(json, MyDTO.class);

如何强制它将 DTO 内部的 Map 转换/保持为 Map&lt;Integer&gt;,而不是 Map&lt;String&gt;

这是我的对象:

public class MultiSeriesTimebasedChartDTO implements Serializable
 {    LinkedHashMap&lt;String, ArrayList&lt;Number&gt;&gt; data;
}

以下是我如何将 JSON 转回对象的代码:

multiSeriesTimebasedChartDTO = gson.fromJson(json, MultiSeriesTimebasedChartDTO.class);

这是结果(在截图中显示),本来是数字,现在变成了字符串。我需要它们作为数字返回。

Gson将HashMap<Integer>转换为对象内的HashMap<String>。

因此,希望找到一个干净的方法来解决这个问题。

我当然可以迭代它,将每个数字从字符串更改回数字,并进行替换... 但我在想可能有其他更好的方法来做这件事。

英文:

I have an object which has a map inside it:

MyDTO 
   HashMap&lt;Integer&gt; 

Now when I convert my MyDTO to JSON (with Gson), and then back from JSON to MyDTO what I get is HashMap&lt;String&gt;.

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&lt;Integer&gt; and NOT as Map&lt;String&gt;?

Here is my Object:

public class MultiSeriesTimebasedChartDTO implements Serializable
 {    LinkedHashMap&lt;String, ArrayList&lt;Number&gt;&gt; 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.

Gson将HashMap<Integer>转换为对象内的HashMap<String>。

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&lt;String,ArrayList&lt;<b>Number</b>&gt;&gt;</code>,Gson会使用其内部类型LazilyParsedNumber,因为它无法确定您希望将Number解析为哪种特定类型。LazilyParsedNumber充当JSON字符串表示的包装器,因此您可以调用相应的Number方法来解析该值。

如果您仅想检索其intValue()doubleValue()等值,LazilyParsedNumber就足够了,但如果想将其与其他数字进行比较,则不行,因为LazilyParsedNumber只等于自身。

由于您的问题提到Map包含Integer值,最简单的解决方案是更改DTO字段的类型:
<pre>
LinkedHashMap&lt;String,ArrayList&lt;<b>Integer</b>&gt;&gt;
</pre>
这样,Gson就知道您想要的确切数字类型,并且可以正确地将JSON数字反序列化为Integers。

英文:

The values are still java.lang.Numbers after the JSON is parsed. However, because your field has the type <code>LinkedHashMap&lt;String, ArrayList&lt;<b>Number</b>&gt;&gt;</code>, Gson uses its internal type LazilyParsedNumber because it cannot know as which specific type you want the Numbers 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&lt;String, ArrayList&lt;<b>Integer</b>&gt;&gt;
</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

Gson将HashMap<Integer>转换为对象内的HashMap<String>。

虽然它实际上将值存储为字符串,但这个类确实是一个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&lt;Integer&gt;" whatever that could be, you have ArrayList&lt;Number&gt;, and that is what GSON has to prepare for:

> public class MultiSeriesTimebasedChartDTO implements Serializable{
> LinkedHashMap<String, ArrayList<Number>> data;
> ^^^^^^^^^^^^^^^^^
> }

Also, you don't have Strings what you complain about, those are LazilyParsedNumbers,

> Gson将HashMap<Integer>转换为对象内的HashMap<String>。

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 Integers, you should simply write that:

public class MultiSeriesTimebasedChartDTO implements Serializable{
  LinkedHashMap&lt;String, ArrayList&lt;Integer&gt;&gt; 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.

huangapple
  • 本文由 发表于 2020年9月4日 14:26:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63735923.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定