Loading IntMaps from JSON with libGDX

libGDX comes with a JSON serializer/deserializer that let’s you move data between JSON files and your Java data structures with just a few lines of code. This works mostly automatically, even with more complex data hierarchies.

We’ll start with an example of how this works, then how it breaks when reading an IntMap, and finally how to fix it.

For the working example, let’s take this class:

And this JSON:

Then you can deserialize the JSON to an ObjectMap with

Boom! Done. You can focus on data structures and data, and not worry about how to move them back and forth. Unless you try to pull the same trick with an IntMap…

Take this JSON:

We know we can load this to an ObjectMap, but if we’re working with integer values, and we want to avoid the hidden allocations that come with autoboxing, then it would be best to load our data to an IntMap, since that’s what it was designed to do. But running this

Results in this error

The deserializer isn’t recognizing the key: value structure of the map, and is trying to use reflection to find field names. I can think of three ways around this.

  1. Read the data to an ObjectMap and manually copy it over to an IntMap.
  2. Change the JSON to write directly to the keyTable[] and valueTable[] fields in the IntMap.
  3. Add a Json.Serializer that works with IntMap.

The first option breaks our ability to read in the data with one line. This isn’t the end of the world, but that extra code will be needed everywhere we read in an IntMap, and we’ll also need to include unused ObjectMaps in our class structures, if the IntMap is a field in MyData for example. For the second option, this approach just seems error-prone to me since it’s working directly with the class internals. Even when it does work, it will mean changing our JSON to reflect the target class rather than the actual data.

The third option is a little more code, but it’s the best way to go. The JSON serializer/deserializer will create a new IntMap, and then move each element from the json object to the map. It will get called automatically whenever you read into an IntMap. It’s a solution I initially saw here, but libGDX is changing all the time, and the code posted there doesn’t work with the current version. So here’s code that works with libGDX 1.0.1.

I included the warning suppressors because there are a lot of compiler complaints about using raw IntMaps without the type specifiers (like IntMap<String>). After you’ve got that class in place, you can make sure it gets used by the JSON loader like this:

Voila! You can now load JSON data directly into an IntMap.

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *