好的,我有这个JSON,我想用Gson解析。我希望Strings成为价值观和长期成为关键。
{" completed_questions":[["字符串" 12345],...]}
问题是数据类型,当我尝试Map<String, Long>
它解析所有内容但由于重复的字符串键而给我一个错误。
我试图改变它,认为Gson会知道要切换它们但是当我尝试Map<Long, String>
时,我得到一个错误,因为我无法解析我的Strings as Longs。
为了让它工作,我创建了一个交换地图类,它接受Key和Value类型,并像public class SwapMap<K, V> implements Map<K, V>
那样交换它们,但是像put / get / remove这样的交换映射操作似乎很难制作工作
即使字符串不是唯一的,使用Gson解析此问题的最佳方法是什么? (但数字是)
答案 0 :(得分:1)
JSON不允许在json对象中的相同级别上使用相同的键。看起来你正在尝试将json数组映射到java映射。
根据以下数据结构,如果要使用Gson提供的默认转换,则需要一个列表。
{
"completed_questions": [
[
"String",
12345
],
[
"String",
12345
]
]
}
这是一个快速实施:
private static void mapToObject() {
String json = "{\"completed_questions\":[[\"String\",12345],[\"String\",123456]]}";
Gson gson = new Gson();
CompletedQuestions questions = gson.fromJson(json, CompletedQuestions.class);
for (List<String> arr : questions.getCompleted_questions()) {
for (String val : arr) {
System.out.print(val + " ");
}
System.out.println();
}
}
public static class CompletedQuestions {
List<List<String>> completed_questions;
public List<List<String>> getCompleted_questions() {
return completed_questions;
}
}
输出:
String 12345
String 123456
需要注意的是,我使用的列表用于映射目的,与提供的数据模型非常相似。
这将要求您自己进行转换。但是json字符串的样子。看起来你需要对指数进行操作。如果您可以控制json结构,我建议创建一个更好的模型。其他明智的你可以做类似list.get(0) - &gt;你的密钥列表.get(1) - &gt;您的值是内部列表中的long
。
答案 1 :(得分:0)
所以我所做的只是制作一个自定义Gson反序列化器,将这些值映射到LongSparseArray<String>
,这是最好的方法。
这是解串器的相关部分:
for (JsonElement array : jsonObject.get("my_key").getAsJsonArray()) {
if (array.getAsJsonArray().size() == 2) {
String value = array.getAsJsonArray().get(VALUE).getAsString();
long key = array.getAsJsonArray().get(KEY).getAsLong();
progress.completedActivities.put(key, value);
}
}
然后我就把它添加到我的Gson创建者中:
@Provides @Singleton Gson provideGson() {
return new GsonBuilder()
.registerTypeAdapter(MyClass.class, new MyClass())
.create();
}