53

Is there a way to convert a String containing json to a HashMap, where every key is a json-key and the value is the value of the json-key? The json has no nested values. I am using the Gson lib.

For example, given JSON:

{
"id":3,
"location":"NewYork"
}

resulting HashMap:

<"id", "3">
<"location", "NewYork">

Thanks

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
Daniel Amerbauer
  • 573
  • 1
  • 4
  • 8
  • @MattBall Seems a pretty unfriendly welcome to a new user. Looking at the answer, it is not at all obvious, and hardly simple. Who uses `TypeToken` for anything, ever? – Eric Wilson Jan 28 '14 at 21:28
  • I'm not really sure what you mean by "a pretty unfriendly welcome." Did I post & forget about an abrasive comment that was just deleted? To answer your question: I don't use GSON, so I don't use `TypeToken`, but I **do** use [the equivalent in Jackson](http://fasterxml.github.io/jackson-core/javadoc/2.2.0/com/fasterxml/jackson/core/type/TypeReference.html) pretty darn frequently. – Matt Ball Jan 28 '14 at 21:37
  • @MattBall You had a comment about asking what had been tried (with a link) and saying that the question was pretty simple. – Eric Wilson Jan 29 '14 at 19:54
  • Related http://stackoverflow.com/questions/2779251/how-can-i-convert-json-to-a-hashmap-using-gson – AlikElzin-kilaka Nov 02 '16 at 11:16

3 Answers3

119

Use TypeToken, as per the GSON FAQ:

Gson gson = new Gson();
Type stringStringMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String,String> map = gson.fromJson(json, stringStringMap);

No casting. No unnecessary object creation.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 4
    What's the import for Type? It gives dozens of options. – ThePixelPony Jun 15 '14 at 12:55
  • 2
    @ThePixelPony read [the `TypeToken#getType()` JavaDoc](http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/reflect/TypeToken.html) for the FQCN of the return type. – Matt Ball Jun 15 '14 at 13:38
  • 7
    `java.lang.reflect.Type stringStringMap = new com.google.gson.reflect.TypeToken>(){}.getType();` – stackoverflowuser2010 Jun 15 '15 at 05:16
  • 2
    This works, but your value type is not respected -- everything is treated as strings. If you change it to `Map` then you'll actually get properly typed values. – Xaero Degreaz Jun 20 '15 at 15:45
  • 1
    @XaeroDegreaz the question subtly suggests that the values should be strings as well, but sure. – Matt Ball Jun 20 '15 at 15:58
  • @Matt Ball Ahh yes, I see the desired output. I was looking at the actual JSON input. – Xaero Degreaz Jun 21 '15 at 18:40
  • @MattBall I have a similar question with Gson [here](http://stackoverflow.com/questions/41029313/how-to-parse-json-into-a-map-using-gson). I wanted to see if you can help me out. I do have a solution but the problem is it looks very messy just to parse a JSON into a Map. – john Dec 08 '16 at 06:14
  • For `Map` Its converting to Double. this is what I am using `Map typeMap = Maps.newHashMap(); new Gson().fromJson(jsonData, typeMap.getClass());` – roottraveller Aug 26 '20 at 14:26
  • `new Gson().fromJson(jsonData, new TypeToken>(){}.getType().getClass());` is converting to `Double` not `Integer`. – roottraveller Aug 26 '20 at 14:29
9

If I use the TypeToken solution with a Map<Enum, Object> I get "duplicate key: null".

The best solution for me is:

String json = "{\"id\":3,\"location\":\"NewYork\"}";
Gson gson = new Gson();
Map<String, Object> map = new HashMap<String, Object>();
map = (Map<String, Object>)gson.fromJson(json, map.getClass());

Result:

{id=3.0, location=NewYork}
alexb83
  • 191
  • 2
  • 8
2

I like:

private static class MyMap extends HashMap<String,String> {};
...
MyMap map = gson.fromJson(json, MyMap.class);