junaidp
junaidp

Reputation: 11211

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

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.

Debugger screenshot showing object values

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

Answers (2)

tevemadar
tevemadar

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 Strings what you complain about, those are LazilyParsedNumbers,

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<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

Marcono1234
Marcono1234

Reputation: 6914

The values are still java.lang.Numbers 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 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:

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

Related Questions