2016-07-07 29 views
0

好的,我有一块我想用Gson解析的JSON。我希望弦乐是成为关键的价值和长处。如何从具有重复键的Json构造一个地图

{ “completed_questions”:[ “字符串”,12345],...]}

的问题是数据类型,当我尝试Map<String, Long>它解析一切,但给了我一个由于重复的String键错误。

我试图扭转它认为Gson会知道切换它们,但当我尝试Map<Long, String>我得到了一个关于不能将我的字符串解析为长的错误。

为了得到它的工作,我创建了一个交换地图类,该类使用Key和Value类型并将它们交换为public class SwapMap<K, V> implements Map<K, V>,但是像put/get/remove那样转换交换的地图操作似乎相当困难。

即使字符串不是唯一的,用Gson解析这个最好的方法是什么? (但数字是)

回答

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(); 
} 
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) - >你的key list.get(1) - >你的值,它是内部列表上的long

+0

是啊,所以我很担心铸造和使用名单。指数();为了搜索,但是这个选项看起来比我的SwapMap类更干净。 – MrEngineer13