Search code examples
javagenericsgsonclasscastexceptiontreemap

TreeMap ClassCastException


Cannot figure out where the String casting is coming from that is causing this ClassCastException. I've cleared out the map so that it only holds a single entry (115,1563) and I ensured both parameters were integers.

First I read from a file and populate the scoreMap.

private void populateScoreMap(String toConvert)
{
    Gson gson = new GsonBuilder().create();

    ScoreRecord.scoreMap = (TreeMap<Integer,Integer>) gson.fromJson(toConvert, ScoreRecord.scoreMap.getClass());

}

ScoreRecord class

public class ScoreRecord
{
    public static SortedMap<Integer,Integer> scoreMap = new TreeMap<Integer, Integer>();
}

Then I try to add an entry in the ScoreGraph class

private void addTodaysScore() {
    Integer todaysScore = getIntent().getIntExtra("score",0);
    Calendar calendar = Calendar.getInstance();
    Integer dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
    ScoreRecord.scoreMap.put(dayOfYear,todaysScore);
    }

Exception

Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at java.lang.Integer.compareTo(Integer.java:1044)
at java.util.TreeMap.put(TreeMap.java:593)
at com.xxx.xxx.xxx.xxx.ScoreGraph.addTodaysScore(ScoreGraph.java:63)

Solution

  • The problem is that the result of ScoreRecord.scoreMap.getClass() is a Java class which does not contain the information relating to generics. In your specific case, it is just SortedMap which is equivalent to SortedMap<Object, Object> rather than SortedMap<Integer, Integer>.

    What you need to do is to create what Gson calls a »type token«. This will give Gson the required hints to be able to parse your collection successfully:

    private void populateScoreMap(String toConvert)
    {
        Gson gson = new GsonBuilder().create();
        Type collectionType = new TypeToken<SortedMap<Integer, Integer>>(){}.getType();
    
        ScoreRecord.scoreMap = gson.fromJson(toConvert, collectionType);
    }
    

    This is also explained in Gson's documentation