Gson - конвертувати з Json в набраний ArrayList <T>


211

Як перетворити рядок JSON ArrayListу користувацький клас за допомогою бібліотеки Gson JsonLog? В основному, JsonLogце інтерфейс, реалізований різними видами журналів, створених моїм додатком Android - журнали SMS, журнали викликів, журнали даних - і це ArrayListсукупність усіх них. Я продовжую отримувати помилку в рядку 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
    }
}

Здається, компілятор не розуміє, що я маю на увазі набраний текст ArrayList. Що мені робити?


Будь ласка, також зверніться до stackoverflow.com/questions/44589381/… про інший підхід
Pankaj Jaiswal

Відповіді:


515

Ви можете використовувати TypeToken для завантаження рядка json у спеціальний об'єкт.

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

Документація:

Являє собою узагальнений тип T .

Java ще не пропонує способу представити загальні типи, так що цей клас є. Примушує клієнтів створити підклас цього класу, який дозволяє отримувати інформацію про тип навіть під час виконання.

Наприклад, щоб створити буквальний тип для List<String>, ви можете створити порожній анонімний внутрішній клас:

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

Цей синтаксис не можна використовувати для створення літералів типу, які мають параметри підстановки, такі як Class<?>або List<? extends CharSequence>.

Котлін:

Якщо вам потрібно зробити це в Котліні, ви можете зробити це так:

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

Або ви можете побачити цю відповідь для різних альтернатив.


3
спробував такий підхід, і у мене з’явилася помилка компіляції, сказавши, що TypeToken () захистив лише доступ
Джонатан

1
@jonney У мене те саме питання. Будь-які рішення?
Zapnologica

15
якщо ви отримуєте захищену помилку доступу, ви залишили { }попереднє.getType()
Zapnologica

@ Алекс десеріалізує спочатку масив, а потім перетворює масив у список або він безпосередньо деріаріалізує список?
Аднан Алі

Цілком корова! Я б подумав, що так ... ну ... ніколи. Дякую.
Джон Уорд

26

Ваш зразок JSON:

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

тому якщо ви хочете зберегти масив модулів у своїх SharedPrefrences так:

1- перетворить ваш повернутий археліст у формат json за допомогою цього методу

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

2- Збережіть його у спільних заздалегідь

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

3- щоб отримати його в будь-який час, отримайте JsonString із загальних уподобань

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

4- перетворити його знову в список масиву

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

це рішення також можливо, якщо ви хочете розібрати ArrayList of Objects Сподіваємось, що це допоможе вам за допомогою бібліотеки Gson .


це правильне рішення, але по суті те саме, що три роки старша відповідь з великою кількістю непотрібної інформації - я не приїхав сюди, щоб дізнатися про спільніПреференції
Xerus

8

Якщо ви хочете використовувати масиви, це досить просто.

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

Укажіть JsonLogяк масивJsonLog[].class


8

Котлін

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)

АБО

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

5

Чому ніхто не написав такий простий спосіб перетворення рядка JSON у Список ?

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

1

Я не впевнений, що стосується gson, але це так, як ви робите це з Jon.sample сподіваюся, що має бути подібний спосіб використання gson

{"Гравці": ["гравець 1", "гравець 2", "гравець 3", "гравець 4", "гравець 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);
                }           
    }
}

@ Sagar Zala: який приклад ви очікуєте ..?
arun kongara

0

У вас є така струна .

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

Тоді ви можете приховати його до ArrayList через Gson типу

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

Ваш клас HotelInfo повинен сподобатися.

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
)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.