Reputation: 11211
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.
Upvotes: 0
Views: 284
Reputation: 13225
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.
Upvotes: 0
Reputation: 6914
The values are still java.lang.Number
s after the JSON is parsed. However, because your field has the type LinkedHashMap<String, ArrayList<Number>>
, 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:
LinkedHashMap<String, ArrayList<Integer>>
This way Gson knows the exact number type you want and can properly deserialize the JSON numbers as Integers.
Upvotes: 1