134

I have a JsonObject named "mapping" with the following content:

{
    "client": "127.0.0.1",
    "servers": [
        "8.8.8.8",
        "8.8.4.4",
        "156.154.70.1",
        "156.154.71.1"
    ]
}

I know I can get the array "servers" with:

mapping.get("servers").getAsJsonArray()

And now I want to parse that JsonArray into a java.util.List...

What is the easiest way to do this?

MikO
  • 18,243
  • 12
  • 77
  • 109
Abel Callejo
  • 13,779
  • 10
  • 69
  • 84
  • 1
    Possible duplicate of [Easy way to change Iterable into Collection](http://stackoverflow.com/q/6416706/978917) or [Convert Iterator to ArrayList](http://stackoverflow.com/q/10117026/978917). – ruakh Aug 31 '13 at 03:21
  • 2
    @ruakh there are many differences between that one and this question. This one deals with `Gson`. – Abel Callejo Aug 31 '13 at 03:24
  • @AbelMelquiadesCallejo have a look at answer.I hope it will solve your problem. – Prateek Aug 31 '13 at 06:29
  • https://stackoverflow.com/a/55691694/470749 was helpful for me. `list.add(item.getAsString());` – Ryan Mar 22 '21 at 16:15

6 Answers6

313

Definitely the easiest way to do that is using Gson's default parsing function fromJson().

There is an implementation of this function suitable for when you need to deserialize into any ParameterizedType (e.g., any List), which is fromJson(JsonElement json, Type typeOfT).

In your case, you just need to get the Type of a List<String> and then parse the JSON array into that Type, like this:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

JsonElement yourJson = mapping.get("servers");
Type listType = new TypeToken<List<String>>() {}.getType();

List<String> yourList = new Gson().fromJson(yourJson, listType);

In your case yourJson is a JsonElement, but it could also be a String, any Reader or a JsonReader.

You may want to take a look at Gson API documentation.

MikO
  • 18,243
  • 12
  • 77
  • 109
  • 10
    `Type` can be found in what package? – Abel Callejo Aug 31 '13 at 15:18
  • 12
    `Type` is a Java built-in interface located in the package `java.lang.reflect` – MikO Aug 31 '13 at 15:40
  • I had to use `getString()` instead of `get()` or else `.fromJson()` was complaining. – lenooh Oct 26 '16 at 18:39
  • @MikO I have a similar question with Gson [here](http://stackoverflow.com/questions/41029313/how-to-parse-json-into-a-map-using-gson). I wanted to see if you can help me out. I do have a solution but the problem is it looks very messy just to parse a JSON into a Map. – john Dec 08 '16 at 06:12
  • **Kotlin Extension** `inline fun String.convertToListObject(): List? { val listType: Type = object : TypeToken?>() {}.type return Gson().fromJson>(this, listType) }` – Mohamed Shawky Jun 28 '22 at 10:46
19

Below code is using com.google.gson.JsonArray. I have printed the number of element in list as well as the elements in List

import java.util.ArrayList;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;


public class Test {

    static String str = "{ "+ 
            "\"client\":\"127.0.0.1\"," + 
            "\"servers\":[" + 
            "    \"8.8.8.8\"," + 
            "    \"8.8.4.4\"," + 
            "    \"156.154.70.1\"," + 
            "    \"156.154.71.1\" " + 
            "    ]" + 
            "}";

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {

            JsonParser jsonParser = new JsonParser();
            JsonObject jo = (JsonObject)jsonParser.parse(str);
            JsonArray jsonArr = jo.getAsJsonArray("servers");
            //jsonArr.
            Gson googleJson = new Gson();
            ArrayList jsonObjList = googleJson.fromJson(jsonArr, ArrayList.class);
            System.out.println("List size is : "+jsonObjList.size());
                    System.out.println("List Elements are  : "+jsonObjList.toString());


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

OUTPUT

List size is : 4

List Elements are  : [8.8.8.8, 8.8.4.4, 156.154.70.1, 156.154.71.1]
Prateek
  • 12,014
  • 12
  • 60
  • 81
11

I read solution from official website of Gson at here

And this code for you:

    String json = "{"client":"127.0.0.1","servers":["8.8.8.8","8.8.4.4","156.154.70.1","156.154.71.1"]}";

    JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
    JsonArray jsonArray = jsonObject.getAsJsonArray("servers");

    String[] arrName = new Gson().fromJson(jsonArray, String[].class);

    List<String> lstName = new ArrayList<>();
    lstName = Arrays.asList(arrName);

    for (String str : lstName) {
        System.out.println(str);
    }    

Result show on monitor:

8.8.8.8
8.8.4.4
156.154.70.1
156.154.71.1
Hoang
  • 829
  • 11
  • 18
  • same answer as the above -- still using the static method `new Gson().fromJson()` – Abel Callejo Sep 22 '17 at 03:51
  • well my problem was other but your snippet solve my problem. I stored the list of string but I wanna fetch the strings. Then your snippet recall me of their I can put String[].class to fetch data. Thank you – badarshahzad May 01 '18 at 09:58
3

Kotlin Extension

for Kotlin developers you can use this extension

inline fun <reified T> String.convertToListObject(): List<T>? {
    val listType: Type = object : TypeToken<List<T?>?>() {}.type
    return Gson().fromJson<List<T>>(this, listType)
}
Mohamed Shawky
  • 159
  • 2
  • 4
2

I was able to get the list mapping to work with just using @SerializedName for all fields.. no logic around Type was necessary.

Running the code - in step #4 below - through the debugger, I am able to observe that the List<ContentImage> mGalleryImages object populated with the JSON data

Here's an example:

1. The JSON

   {
    "name": "Some House",
    "gallery": [
      {
        "description": "Nice 300sqft. den.jpg",
        "photo_url": "image/den.jpg"
      },
      {
        "description": "Floor Plan",
        "photo_url": "image/floor_plan.jpg"
      }
    ]
  }

2. Java class with the List

public class FocusArea {

    @SerializedName("name")
    private String mName;

    @SerializedName("gallery")
    private List<ContentImage> mGalleryImages;
}

3. Java class for the List items

public class ContentImage {

    @SerializedName("description")
    private String mDescription;

    @SerializedName("photo_url")
    private String mPhotoUrl;

    // getters/setters ..
}

4. The Java code that processes the JSON

    for (String key : focusAreaKeys) {

        JsonElement sectionElement = sectionsJsonObject.get(key);
        FocusArea focusArea = gson.fromJson(sectionElement, FocusArea.class);
    }
Gene Bo
  • 11,284
  • 8
  • 90
  • 137
  • how i access to content image using this way? – Adnan haider Apr 09 '21 at 11:22
  • @Adnanhaider, if I understood your question, you want to actually load the image in a viewer? In the example here, that is what the image url is for. Here's a thread on how to do so in Android https://stackoverflow.com/questions/5776851/load-image-from-url – Gene Bo Apr 09 '21 at 16:26
  • i have two class 1. main 2 list shape class. 1 class as parent which attribute is name,id,address, 2 class children, where child name, class name , school name etc. now after set getter setter in model class i get data from json mvvm method and i want to access getter of child class , i only access parent class not child class which give me headache for 2 days still not find answer. so how i access attribute of child class which is already as arraylist . – Adnan haider Apr 10 '21 at 04:31
  • @Adnanhaider, I didn't see this message before, justing seeing today. It sounds like a non-trivial setup. I would suggest to create a new post and there list minimal code in clean block to demo what you are working with and what you would like it to be doing – Gene Bo May 10 '21 at 16:59
0

Given you start with mapping.get("servers").getAsJsonArray(), if you have access to Guava Streams, you can do the below one-liner:

List<String> servers = Streams.stream(jsonArray.iterator())
                              .map(je -> je.getAsString())
                              .collect(Collectors.toList());

Note StreamSupport won't be able to work on JsonElement type, so it is insufficient.

Alex Moore-Niemi
  • 2,913
  • 2
  • 24
  • 22