I want to convert a class which contains a Hashmap of non-primitive keys or values to Json using Gson.
so I realize that Hashmap keys and values are stored only as Strings when serializing with Gson. so I can’t serialize them. I ran into this solution which should be fine, but I get this error:
java: cannot find symbol symbol: class TypeAdapterRuntimeTypeWrapper location: class TypeAdapters.MapTypeAdapterFactory.Adapter<K,V>
any idea?
EDIT:
this is my code:
public class App {
public static void main(String[] args) throws Exception {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
GameController gameController = new GameController();
System.out.println(gson.toJson(gameController));
}
}
class GameController
{
HashMap<Tile, TileState> map = new HashMap<>();
public GameController()
{
map.put(new Tile(), TileState.VISIBLE);
map.put(new Tile(), TileState.REVEALED);
}
}
class Tile
{
@Override
public int hashCode() {
return super.hashCode();
}
}
enum TileState
{
REVEALED,
VISIBLE
}
and the output is:
{
"map": {
"dir.Tile@6996db8": "REVEALED",
"dir.Tile@368102c8": "VISIBLE"
}
}
Advertisement
Answer
I ran into this solution which should be fine, but I get this error:
java: cannot find symbol symbol: class TypeAdapterRuntimeTypeWrapper location: class TypeAdapters.MapTypeAdapterFactory.Adapter<K,V>any idea?
MapTypeAdapterFactory is an internal Gson class; you should not copy its source to your project because:
- In case bugs are found in that class and fixed in the Gson project, your copy would still contain those bugs
- This internal class itself depends on other internal classes, in this case
TypeAdapterRuntimeTypeWrapper, which is why you are seeing this compilation error
Instead, try to use the functionality Gson provides out-of-the-box. The User Guide explains how Map serialization works and how you can customize it. Unfortunately due to legacy reasons Gson uses toString() for serialization. There are a few possible solutions:
- Override
toString()to return a more reasonable representation, and register aTypeAdapterwhich handles deserialization - Only register a
TypeAdapterwhich handles both serialization and deserialization, and useGsonBuilder.enableComplexMapKeySerialization() - Only use
GsonBuilder.enableComplexMapKeySerialization(). In that case Gson will use reflection to serialize and deserializeTileinstances
Also, as side note: Your Tile class looks a bit incorrect:
- Normally when using a class as key of a
Mapyou overrideequalsandhashCode; otherwise instances are compared by reference equality only, and separate instances with the same field values are not considered equal - When overriding
hashCode()you normally also overrideequals(Object) - Just calling
super.hashCode()in yourhashCode()implementation has no special effect and behaves the same way as if you had not overridden the method