gozzilli
gozzilli

Reputation: 8337

JSONObject from HashMap - Cast to String failed

I need to create a JSONObject from a HashMap of a custom class's toString and a float value. I tried the code below hoping that it would just work:

public class MyClass {
    ...
    public String toString() {
        return "a nice string"
    }
}


HashMap<MyClass,Float> map = new HashMap<MyClass,Float>();
map.put(...);

JSONObject json = new JSONObject(map);

But I get:

java.lang.ClassCastException: MyClass cannot be cast to java.lang.String

What's the best way to create this JSONObject? Thanks.

Upvotes: 0

Views: 4064

Answers (3)

gozzilli
gozzilli

Reputation: 8337

Both Gamb's and Abu's answers are correct and helped me to get to my final result.

I solved my problem like this:

HashMap<MyClass,Float> obj = functionThatReturnsThisStructure();

JSONObject jsonObj = new JSONObject();

for (Entry<MyClass,Float> entry: obj.entrySet()) {
    jsonObj.put(entry.getKey().toString(), entry.getValue());
}

Upvotes: 0

Fritz
Fritz

Reputation: 10045

Seems like you're using the org.json library. If you take a look at the code of the JSONObject class, apparently they're not using generics.

public JSONObject(Map map) {
    this.map = new HashMap();
    if (map != null) {
        Iterator i = map.entrySet().iterator();
        while (i.hasNext()) {
            Map.Entry e = (Map.Entry)i.next();
            Object value = e.getValue();
            if (value != null) {
                this.map.put(e.getKey(), wrap(value));
            }
        }
    }
}

This map seems to handle entries with a String key and an Object value by the look of the keyPool map they use to manage unique String keys. In the comments, its also stated that:

This is used by JSONObject.put(string, object).

So it would be correct to assume the keys of the JSON objects are Strings.

Your MyClass type can't be upcasted to String directly (String is not a superclass of MyClass), that's why the constructor is actually complaining about the map, because it needs a map of the form HashMap<String,Object> (Note that there's no problem with Float and Object).

To fix the issue, you have to define a HashMap<String,Float> where you should store a String representation of your MyClass object either by using toString.

If you can't use a String you can consider using an intermediate structure that maps a code represented with a String to a certain MyClass object, so you can retain your MyClass class.

Upvotes: 1

Abubakkar
Abubakkar

Reputation: 15644

You need to change this:

HashMap<MyClass,Float> map = new HashMap<MyClass,Float>();

with

HashMap<String,Float> map = new HashMap<String,Float>();

as you said "HashMap of a custom class's toString and a float value"

You haven't mentioned how are you putting the values into the hashmap.

But if you using toString method of your custom class, then you should put it like :

MyClass m = new MyClass();
map.put(m.toString,123.45f);

Upvotes: 2

Related Questions