Gson: convierta de Json a una ArrayList escrita <T>

211

Usando la biblioteca Gson, ¿cómo convierto una cadena JSON en una ArrayListde una clase personalizada JsonLog? Básicamente, JsonLoges una interfaz implementada por diferentes tipos de registros creados por mi aplicación de Android: registros de SMS, registros de llamadas, registros de datos, y esta ArrayListes una colección de todos ellos. Sigo recibiendo un error en la línea 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
    }
}

Parece que el compilador no entiende que me estoy refiriendo a un tipeado ArrayList. ¿Qué debo hacer?

Matthew Quiros
fuente
Consulte también stackoverflow.com/questions/44589381/… para otro enfoque
Pankaj Jaiswal,

Respuestas:

516

Puede usar TypeToken para cargar la cadena json en un objeto personalizado.

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

Documentación:

Representa un tipo genérico T .

Java aún no proporciona una forma de representar tipos genéricos, por lo que esta clase sí. Obliga a los clientes a crear una subclase de esta clase que permite recuperar la información de tipo incluso en tiempo de ejecución.

Por ejemplo, para crear un tipo literal para List<String>, puede crear una clase interna anónima vacía:

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

Esta sintaxis no se puede usar para crear literales de tipo que tengan parámetros comodín, como Class<?>o List<? extends CharSequence>.

Kotlin:

Si necesita hacerlo en Kotlin , puede hacerlo así:

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

O puede ver esta respuesta para varias alternativas.

Alex
fuente
3
probé este enfoque y recibí un error de compilación que decía que TypeToken () solo tenía acceso protegido
Jonathan
1
@ Jonney tengo el mismo problema. ¿Alguna solución?
Zapnologica
15
si está recibiendo un error de acceso protegido, dejó de lado el { }anterior.getType()
Zapnologica
@Alex, ¿se deserializa primero en una matriz y luego esa matriz se convierte en Lista o se deserializa directamente en Lista?
Adnan Ali
Totalmente vaca! Me habría imaginado que ... bueno ... nunca. Gracias.
John Ward,
26

Su muestra JSON es:

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

así que si desea guardar una lista de módulos en sus SharedPrefrences, entonces:

1- convertirá su lista de matrices devuelta para formato json usando este método

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

2- Guárdalo en preferencias compartidas

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

3- para recuperarlo en cualquier momento, obtenga JsonString de preferencias compartidas como esa

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

4- conviértalo de nuevo a la lista de matriz

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());

Esta solución también es factible si desea analizar ArrayList of Objects. Espero que sea útil mediante el uso de la Biblioteca Gson .

Mohamed Hussien
fuente
esta es la solución correcta, pero esencialmente los mismos que los tres años mayor respuesta con una gran cantidad de información innecesarios - No he venido aquí para aprender sobre SharedPreferences
Xerus
8

Si desea utilizar matrices, es bastante simple.

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

Proporcionar el JsonLogcomo una matrizJsonLog[].class

Ali Asadi
fuente
8

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)

O

val playerArray = Gson().fromJson(json, Array<Player>::class.java)
murgupluoglu
fuente
5

¿Por qué nadie escribió esta forma simple de convertir cadenas JSON en List ?

List<Object> list = Arrays.asList(new GsonBuilder().create().fromJson(jsonString, Object[].class));
FarukT
fuente
1

No estoy seguro acerca de gson, pero así es como lo haces con Jon. Espero que haya una forma similar de usar gson

{"Jugadores": ["jugador 1", "jugador 2", "jugador 3", "jugador 4", "jugador 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);
                }           
    }
}
arun kongara
fuente
@ Sagar Zala: ¿qué ejemplo estás esperando?
arun kongara
0

Tienes una cuerda como esta.

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

Luego puedes convertirlo a ArrayList a través de Gson como

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

Su clase HotelInfo debería gustarle esto.

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
)
Shihab Uddin
fuente