如何从具有重复键的Json构造Map

时间:2016-07-07 22:11:47

标签: android json dictionary gson

好的,我有这个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解析此问题的最佳方法是什么? (但数字是)

2 个答案:

答案 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();
}
相关问题