Gson-从Json转换为类型化ArrayList <T>


211

使用Gson库,如何将JSON字符串转换ArrayList为自定义类的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
    }
}

看来编译器无法理解我指的是typed ArrayList。我该怎么办?


另请参见stackoverflow.com/questions/44589381/…以了解另一种方法
Pankaj Jaiswal

Answers:


515

您可以使用TypeToken将json字符串加载到自定义对象中。

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

说明文件:

表示泛型类型牛逼

Java尚未提供表示通用类型的方法,因此此类提供了。强制客户端创建此类的子类,即使在运行时也可以检索类型信息。

例如,要为创建类型文字List<String>,您可以创建一个空的匿名内部类:

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

此语法不能用于创建具有通配符参数(例如Class<?>或)的类型文字List<? extends CharSequence>

科特林:

如果您需要在Kotlin中进行操作,则可以这样操作:

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

或者,您可以在各种替代方案中看到此答案


3
尝试了这种方法,我得到一个编译错误,说TypeToken()仅保护访问权限
Jonathan

1
@jonney我有同样的问题。有什么办法吗?
Zapnologica

15
如果您遇到受保护的访问错误,则可以忽略{ }之前的内容.getType()
Zapnologica 2015年

@Alex是先反序列化为Array,然后将该数组转换为List还是直接反序列化为List?
阿德南·阿里

牛!我本来会以为……嗯……从来没有。谢谢。
约翰·沃德

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-将使用此方法将返回的arraylist转换为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,此解决方案也是可行的。希望它可以通过使用Gson Library帮助您。


这是正确的解决方案,但本质上是相同的三年以上的答案有很多不必要的信息-我不是来这里学习sharedPreferences
Xerus


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

为什么没人在List中编写这种简单的方法来转换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:您期望的例子是什么?
阿伦·孔加拉

0

你有一个像这样的字符串

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

然后您可以像这样通过Gson将其隐藏到ArrayList

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
)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.