Gson to Model containing several return types for one key i just had a problem converting the JSON from Phillips Hue Lights (Response) to a Model. Since it may contain several "unknown" keys in success and/or may contain just a String for success i had to write/use a TypeAdapter and a deserializer aswell. This works but im pretty sure there is a better way to solve this.

Dummy JSONS:

[{"success":{"/config/name":"My bridge"}}]


and

[{
    "success":{"id": "3"}
}]


and 

[
{"success":{ "address": "/groups/1/action/on", "value": true}},
{"success":{ "address": "/groups/1/action/effect", "value":"colorloop"}},
{"success":{ "address": "/groups/1/action/hue", "value":6000}}
]


And the JSON with just a String

[{
    "success": "/config/whitelist/1234567890 deleted."
}]


It may also contain "error" but this isnt the problem. Since the object in address is unknown i use a Adapter from https://stackoverflow.com/questions/17627869/simple-way-to-strip-outer-array-of-responses-in-gson which works fine as long as its an Object. Since it may also contain a String i had to create a JsonDeserializer which validates if its a JSONObject and if not, it sets another variable in the Model with the message. It works, but i always have to revalidate if the message or success it set.

This is my JSONDeserializer

public class HueResponseDeserializer implements JsonDeserializer&lt;HueResponse&gt; {
    private final String TAG = HueResponseDeserializer.class.getSimpleName();

    @Override
    public HueResponse deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {

        HueResponse response = new HueResponse();
        JsonObject jsonObject = jsonElement.getAsJsonObject();
        if (jsonObject.get("success").isJsonObject()) {
            for (Map.Entry&lt;String, JsonElement&gt; entry : jsonObject.getAsJsonObject("success").entrySet()) {
                response.setSuccess(new HashMap&lt;String, Object&gt;() {{
                    put(entry.getKey(), entry.getValue());
                }});
            }
        } else {
            response.setSuccessMessage(jsonObject.get("success").getAsString());
        }

        if (jsonObject.has("error") &amp;&amp; jsonObject.get("error").isJsonObject()) {
            for (Map.Entry&lt;String, JsonElement&gt; entry : jsonObject.getAsJsonObject("error").entrySet()) {
                response.setError(context.deserialize(entry.getValue(), HueResponse.Error.class));
            }
        }
        return response;
    }
}


And my Model

public class HueResponse {

    private Map&lt;String, Object&gt; success;
    private Error error;
    private String successMessage;

    public String getSuccessMessage() {
        return successMessage;
    }

    public void setSuccessMessage(String successMessage) {
        this.successMessage = successMessage;
    }

    public Map&lt;String, Object&gt; getSuccess() {
        return success;
    }

    public Error getError() {
        return error;
    }

    public void setSuccess(Map&lt;String, Object&gt; success) {
        this.success = success;
    }

    public void setError(Error error) {
        this.error = error;
    }

    public static class Error {
        private int type;
        private String address;
        private String description;

        public int getType() {
            return type;
        }

        public String getAddress() {
            return address;
        }

        public String getDescription() {
            return description;
        }


        @Override
        public String toString() {
            return "Type: " + this.type
                    + " Address: " + this.address
                    + " Description: " + this.description;
        }
    }

}
Iterating through an entrySet()

If what you really want is to put all the JSON objects into a success map, rather than overwriting each of them with every iteration, there's a way to stream it:

Map&lt;String, Object&gt; map = object.entrySet().stream()
                                .collect(Collectors.toMap(Entry::getKey, 
                                            entry -&gt; (Object) entry.getValue()));
result.setSuccess(map);


In any case, a more fluent implementation of HashMap&lt;&gt;() {{ ... }} is to use Collections.singletonMap():

object.entrySet().forEach(entry -&gt; { 
    Map&lt;String, Object&gt; map = Collections.singletonMap(entry.getKey(), entry.getValue()); 
    // ...
});


Modeling

You can consider have a more domain-based modeling of the successful results, instead of a simple Map&lt;String, Object&gt; in your HueResponse. For example, consider a Group of Action objects that have a state consisting of enabled (aka on), effect and hue? That seems to adhere closer to the results, giving you a more meaningful application.