Recursive HashMap

1,229 views
Skip to first unread message

Jerry

unread,
Jul 8, 2011, 8:15:43 PM7/8/11
to google-gson
Hi guys,

I'm new to Gson and I read the user guide. I did some tests using gson
but I wasn't able to get accomplish deserialization of a recursive
hashmap.

For instance, the recursive hashmap has N level, the top level has the
type HashMap<String,Object>. Object might contain another
HashMap<String, Object>. User passes in the HashMap<String,Object> and
I need to figure out the number of levels in the map and create a
typeToken from it in order to deserialize it later on.

What is the best approach to accomplish this using gson?

Best Regards,

Jerry

Programmer Bruce

unread,
Jul 9, 2011, 1:29:30 PM7/9/11
to googl...@googlegroups.com
I'd just recursively deserialize it manually; never mind trying to figure out a TypeToken.

JsonElement je = new JsonParser().parse(json);
JsonObject jo = je.getAsJsonObject();

Map<String, Object> map = createMapFromJsonObject(jo);

//...

static Map<String, Object> createMapFromJsonObject(
    JsonObject jo)
{
  Map<String, Object> map = new HashMap<String, Object>();
  for (Entry<String, JsonElement> entry : jo.entrySet())
  {
    String key = entry.getKey();
    JsonElement value = entry.getValue();
    map.put(key, getValueFromJsonElement(value));
  }
  return map;
}

static Object getValueFromJsonElement(JsonElement je)
{
  if (je.isJsonObject())
  {
    return createMapFromJsonObject(je.getAsJsonObject());
  }
  else if (je.isJsonArray())
  {
    JsonArray array = je.getAsJsonArray();
    List<Object> list = new ArrayList<Object>(array.size());
    for (JsonElement element : array)
    {
      list.add(getValueFromJsonElement(element));
    }
    return list;
  }
  else if (je.isJsonNull())
  {
    return null;
  }
  else // must be primitive
  {
    JsonPrimitive p = je.getAsJsonPrimitive();
    if (p.isBoolean()) return p.getAsBoolean();
    if (p.isString()) return p.getAsString();
    // else p is number, but don't know what kind
    String s = p.getAsString();
    try
    {
      return new BigInteger(s);
    }
    catch (NumberFormatException e)
    {
      // must be a decimal
      return new BigDecimal(s);
    }
  }
}

-Bruce

Jerry

unread,
Jul 9, 2011, 9:59:11 PM7/9/11
to googl...@googlegroups.com
Hi Bruce:

This is very helpful. I really appreciate it. It taught me how to use the JsonObject and parsing the json. 
From the performance perspective, do you think using TypeToken and fromJson is faster than desirializing it ourselves?

Best Regards,

Jerry

Programmer Bruce

unread,
Jul 10, 2011, 5:23:41 PM7/10/11
to googl...@googlegroups.com
No.  The opposite.  It's often faster to manually parse and build, rather than use the fancy binding features.  The binding features are just much more convenient -- 1 line solutions instead of 100 lines.

According to the performance tests at https://github.com/eishay/jvm-serializers/wiki using Gson databind is almost 7x slower than using Gson manual processing.  (The next update to these tests should include performance tests of Gson manual/tree processing, which I guess will perform closer to manual processing than databind processing.)

-Bruce

Jerry

unread,
Jul 11, 2011, 12:20:30 PM7/11/11
to google-gson
Hi Bruce:

Thanks for sharing with me the performance benchmark. It really puts
things into perspective regarding the databinding processing and
manual processing.

Do you think gson will provide some traversal abilities like jxpath in
the future? For now, if I would like to locate a key deep down in
recursive hashmap, I think I need to parse it manually to find the
key. Am I correct or there is a better way to do this with the help of
other libraries?

Best Regards,

Jerry

On Jul 10, 5:23 pm, Programmer Bruce <programmerbr...@gmail.com>
wrote:
> No.  The opposite.  It's often faster to manually parse and build, rather
> than use the fancy binding features.  The binding features are just much
> more convenient -- 1 line solutions instead of 100 lines.
>
> According to the performance tests athttps://github.com/eishay/jvm-serializers/wikiusing Gson databind is almost

Programmer Bruce

unread,
Jul 11, 2011, 4:57:59 PM7/11/11
to googl...@googlegroups.com
There are at least two Java-to/from-JSON libraries that provide xpath-like querying, but they're both slow compared to the faster solutions.

Though Gson databind is significantly slower than Gson manual or Gson manual/tree processing, it's still fast enough for many situations, and of course, one would do well to use tests to find bottlenecks in an application, and not guesswork.

Depending on the specific selection criteria, using the Gson streaming API might be easy and fast enough to get the target data.  http://sites.google.com/site/gson/streaming

-Bruce

Reply all
Reply to author
Forward
0 new messages