Gson - convert from Json to a typed ArrayList<T>
Asked Answered
V

9

257

Using the Gson library, how do I convert a JSON string to an ArrayList of a custom class JsonLog? Basically, JsonLog is an interface implemented by different kinds of logs made by my Android app--SMS logs, call logs, data logs--and this ArrayList is a collection of all of them. I keep getting an error in line 6.

public static void log(File destination, JsonLog log) {
    Collection<JsonLog> logs = null;
    if (destination.exists()) {
        Gson gson = new Gson();
        BufferedReader br = new BufferedReader(new FileReader(destination));
        logs = gson.fromJson(br, ArrayList<JsonLog>.class); // line 6
        // logs.add(log);
        // serialize "logs" again
    }
}

It seems the compiler doesn't understand I'm referring to a typed ArrayList. What do I do?

Volscian answered 12/9, 2012 at 8:29 Comment(1)
Please also refer to #44589881 for another approachGlut
E
614

You may use TypeToken to load the json string into a custom object.

logs = gson.fromJson(br, new TypeToken<List<JsonLog>>(){}.getType());

Documentation:

Represents a generic type T.

Java doesn't yet provide a way to represent generic types, so this class does. Forces clients to create a subclass of this class which enables retrieval the type information even at runtime.

For example, to create a type literal for List<String>, you can create an empty anonymous inner class:

TypeToken<List<String>> list = new TypeToken<List<String>>() {};

This syntax cannot be used to create type literals that have wildcard parameters, such as Class<?> or List<? extends CharSequence>.

Kotlin:

If you need to do it in Kotlin you can do it like this:

val myType = object : TypeToken<List<JsonLong>>() {}.type
val logs = gson.fromJson<List<JsonLong>>(br, myType)

Or you can see this answer for various alternatives.

Estrous answered 12/9, 2012 at 8:34 Comment(10)
tried this approach and i got a compile error saying TypeToken() has protected access onlySpecify
@jonney I have the same issue. Any solutions?Alcatraz
if you are getting has protected access error, you left out the { } before .getType()Alcatraz
@Estrous does it deserialize first to an Array then that Array is converted into List or does it directly deserialize to List ?Caryopsis
Wholly cow! I would have figured that like...well...never. Thank you.Cordeelia
To me this looked like "whatever it is, it will NEVER work". It worked. Now I really need to take some time to understand it. Thanks for sharing!Southerland
Is there an explanation to this?Subglacial
@Ab_ take a look at the TypeToken documentation, it explain what it does: google.github.io/gson/apidocs/com/google/gson/reflect/…Estrous
Kotlin instructions here: #33381884Overnice
Been coming back to this reply once in a while. But, Kotlin example was a cherry on the icing!Pinchpenny
I
30

Your JSON sample is:

{
    "status": "ok",
    "comment": "",
    "result": {
    "id": 276,
    "firstName": "mohamed",
    "lastName": "hussien",
    "players": [
            "player 1",
            "player 2",
            "player 3",
            "player 4",
            "player 5"
    ]
}

so if you want to save arraylist of modules in your SharedPrefrences so :

1- will convert your returned arraylist for json format using this method

public static String toJson(Object jsonObject) {
    return new Gson().toJson(jsonObject);
}

2- Save it in shared prefreneces

PreferencesUtils.getInstance(context).setString("players", toJson((.....ArrayList you want to convert.....)));

3- to retrieve it at any time get JsonString from Shared preferences like that

String playersString= PreferencesUtils.getInstance(this).getString("players");

4- convert it again to array list

public static Object fromJson(String jsonString, Type type) {
    return new Gson().fromJson(jsonString, type);
}

ArrayList<String> playersList= (ArrayList<String>) fromJson(playersString,
                    new TypeToken<ArrayList<String>>() {
                    }.getType());

this solution also doable if you want to parse ArrayList of Objects Hope it's help you by using Gson Library .

Ilan answered 23/2, 2015 at 9:14 Comment(1)
this is the correct solution, but essentially the same as the three years older answer with a lot of unneccessary information - I didn't come here to learn about sharedPreferencesAdz
C
14

Why nobody wrote this simple way of converting JSON string in List ?

List<Object> list = Arrays.asList(new GsonBuilder().create().fromJson(jsonString, Object[].class));
Correlation answered 26/3, 2020 at 9:49 Comment(1)
Because the poster wants the list to be a specific type. It's literally right there in the title of the question. Also, you can just use new Gson() instead of new GsonBuilder().create().Ariadne
T
12

Kotlin

data class Player(val name : String, val surname: String)

val json = [
  {
    "name": "name 1",
    "surname": "surname 1"
  },
  {
    "name": "name 2",
    "surname": "surname 2"
  },
  {
    "name": "name 3",
    "surname": "surname 3"
  }
]

val typeToken = object : TypeToken<List<Player>>() {}.type
val playerArray = Gson().fromJson<List<Player>>(json, typeToken)

OR

val playerArray = Gson().fromJson(json, Array<Player>::class.java)
Tubulate answered 28/10, 2019 at 8:24 Comment(0)
F
9

If you want to use Arrays, it's pretty simple.

logs = gson.fromJson(br, JsonLog[].class); // line 6

Provide the JsonLog as an array JsonLog[].class

Fusain answered 12/12, 2018 at 12:59 Comment(0)
S
8

If you want convert from Json to a typed ArrayList , it's wrong to specify the type of the object contained in the list. The correct syntax is as follows:

 Gson gson = new Gson(); 
 List<MyClass> myList = gson.fromJson(inputString, ArrayList.class);
Servo answered 25/11, 2020 at 23:8 Comment(0)
W
7

Let's say, You have a string like this.

"[{"id":2550,"cityName":"Langkawi","hotelName":"favehotel Cenang Beach - Langkawi","hotelId":"H1266070"},
{"id":2551,"cityName":"Kuala Lumpur","hotelName":"Metro Hotel Bukit Bintang","hotelId":"H835758"}]"

Then you can covert it to ArrayList via Gson like

var hotels = Gson().fromJson(historyItem.hotels, Array<HotelInfo>::class.java).toList()

Your HotelInfo class should like this.

import com.squareup.moshi.Json

data class HotelInfo(

    @Json(name="cityName")
    val cityName: String? = null,

    @Json(name="id")
    val id: Int? = null,

    @Json(name="hotelId")
    val hotelId: String? = null,

    @Json(name="hotelName")
    val hotelName: String? = null
)
Waler answered 13/4, 2020 at 5:29 Comment(0)
L
1

I am not sure about gson but this is how you do it with Jon.sample hope there must be similar way using gson

{ "Players": [ "player 1", "player 2", "player 3", "player 4", "player 5" ] }

===============================================

import java.io.FileReader;
import java.util.List;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

public class JosnFileDemo {

    public static void main(String[] args) throws Exception
    {
        String jsonfile ="fileloaction/fileName.json";


                FileReader reader = null;
                JSONObject jsb = null;
                try {
                    reader = new FileReader(jsonfile);
                    JSONParser jsonParser = new JSONParser();
                     jsb = (JSONObject) jsonParser.parse(reader);
                } catch (Exception e) {
                    throw new Exception(e);
                } finally {
                    if (reader != null)
                        reader.close();
                }
                List<String> Players=(List<String>) jsb.get("Players");
                for (String player : Players) {
                    System.out.println(player);
                }           
    }
}
Ledezma answered 20/11, 2018 at 3:28 Comment(1)
@ Sagar Zala :what's example you are expecting ..?Ledezma
C
0

In Kotlin For sending : If you send Arraylist

Gson().toJson(arraylist)

For receiving: If you receive ArrayList

var arraylist = Gson().fromJson(argument, object : TypeToken<ArrayList<LatLng>>() {}.type)  

For sending : If you send ModelClass( e.g. LatLngModel.class)

var latlngmodel = LatlngModel()
latlngmodel.lat = 32.0154
latlngmodel.lng = 70.1254

Gson().toJson(latlngModel)

For receiving: If you receive ModelClass

var arraylist = Gson().fromJson(argument,LatLngModel::class.java )  
Comparable answered 14/3, 2022 at 12:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.