【问题标题】:Android convert String to HashMapAndroid 将 String 转换为 HashMap
【发布时间】:2013-02-07 15:48:33
【问题描述】:

我有一个类似这样的字符串:

[ { "1":33 }, { "2":30 }, { "3":15 }, { "4":23 }, ...{ "9":17 },... { "U":2 }, { "V":22 }, { "W":1 }, { "X":35 }, { "Y":6 }, { "Z":19 } ]

结构是{"key":value}。我需要将其转换为表/HashMap,以便我可以根据键获取值。

我尝试使用 Gson 但失败了。有没有更简单的方法,比如使用一些序列化?

TIA

【问题讨论】:

  • 这是 JSON 格式.. 所以使用 JSON 并将那些 Json 对象放在 HashMap 中
  • 仅使用正则表达式查看我的工作代码

标签: java android regex json


【解决方案1】:

编写您自己的简单解析器。从头开始读取每个字符,当您看到一个“然后开始将下一个字符开始视为键的开始并在出现下一个”时,现在点击它键,然后寻找一个:然后记录值直到您看到一个空格或一个}。再次重复此过程,直到您读取了字符串中的所有字符。这样,如果有 n 个字符,那么它将在 O(n) 中解决

【讨论】:

    【解决方案2】:

    使用我做的这个方法:

    public HashMap<String, Integer> convertToHashMap(String jsonString) {
            HashMap<String, Integer> myHashMap = new HashMap<String, Integer>();
            try {
                JSONArray jArray = new JSONArray(jsonString);
                JSONObject jObject = null;
                String keyString=null;
                for (int i = 0; i < jArray.length(); i++) {
                    jObject = jArray.getJSONObject(i);
                    // beacuse you have only one key-value pair in each object so I have used index 0 
                    keyString = (String)jObject.names().get(0);
                    myHashMap.put(keyString, jObject.getInt(keyString));
                }
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return myHashMap;
        }
    

    使用:

    String myString = "[ { \"1\":33 }, { \"2\":30 }, { \"3\":15 }, { \"4\":23 }, { \"9\":17 }, { \"U\":2 }, { \"V\":22 }, { \"W\":1 }, { \"X\":35 }, { \"Y\":6 }, { \"Z\":19 } ]";
    HashMap<String, Integer> map = convertToHashMap(myString);
    Log.d("test", map.toString());
    

    您也可以使用map.keySet()获取所有密钥

    【讨论】:

      【解决方案3】:

      你有一个对象数组,每个对象都不同(它有不同的字段)。 JSON 解析器在谈论将其反序列化为对象时会遇到问题。 Gson 用户指南specifically mentions this。

      您可以使用 Gson,但您将不得不使用他们建议的方法之一。创建返回 Map 的自定义反序列化器将相当简单。您需要遍历数组,获取每个对象,然后提取字段和值:

      // create this class so as not to affect other Map types:
      class MyMap extends HashMap<String, Integer> {}
      
      class MyMapDeserializer implements JsonDeserializer<MyMap> 
      {
          public MyMap deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) 
                throws JsonParseException 
          {
              JsonArray ja = je.getAsJsonArray();
              MyMap map = new MyMap();
              for (int i = 0; i < ja.size(); i++) 
              {
                  JsonObject jo = ja.get(i).getAsJsonObject();
                  Set<Entry<String, JsonElement>> set = jo.entrySet();
                  for (Entry<String, JsonElement> e : set) 
                  {
                      map.put(e.getKey(), e.getValue().getAsInt());
                  }
              }
              return map;
          }
      }
      

      您通过以下方式使用它:

      Gson gson = new GsonBuilder()
                      .registerTypeAdapter(MyMap.class, new MyMapDeserializer())
                      .create();
      
      MyMap mm = gson.fromJson(jsonString, MyMap.class);
      

      【讨论】:

        【解决方案4】:

        您可以使用正则表达式使用此代码:

            Map<String, String> map = new HashMap<String, String>();
            //!!Your string comes here, I escape double quoutes manually !!
            String str = "\"[ { \"1\":33 }, { \"2\":30 }, { \"3\":15 }, { \"4\":23 }, { \"9\":17 }, {\"U\":2 }, { \"V\":22 }, { \"W\":1 }, { \"X\":35 }, { \"Y\":6 }, { \"Z\":19 } ]\"";
            String regex = "\\{\\s*\"(\\w+)\":(\\d+)\\s*\\}";
        
        
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(str);
        
            while (matcher.find()) {
                String key = matcher.group(1);
                String value = matcher.group(2);
                System.out.println(key + " " + value);
                map.put(key, value);
            }
        

        打印:

        1 33
        2 30
        3 15
        4 23
        9 17
        U 2
        V 22
        W 1
        X 35
        Y 6
        Z 19
        

        注意:如果您想要Map&lt;String,Integer&gt;,请更改定义并使用Integer.parseInt() 从字符串中获取整数。

        【讨论】:

          【解决方案5】:
          public static void main(String[] args) {
              String s = "{ 1:33 }, { 2:30 }, { 3:15 }, { 4:23 }, { 9:17 }, { U:2 }, { V:22 }, { W:1 }, { X:35 }, { Y:6 }, { Z:19 }";
              String[] arr = s.split(", ");
              Map<String, Integer> map = new HashMap<String, Integer>();
              for (String str : arr) {
                  str = str.replace("{", "").replace("}", "");
                  String[] splited = str.split(":");
          
                  map.put(splited[0], Integer.parseInt(splited[1].trim()));
          
              }
              System.out.println(map);
          
          }
          

          输出:

          { 9=17,  Z=19,  Y=6,  X=35,  1=33,  3=15,  2=30,  W=1,  V=22,  4=23,  U=2}
          

          【讨论】:

          • 他的初始字符串不同
          • @NikolayKuznetsov 这不是他上面写的字符串。
          • @NikolayKuznetsov 你的代码在做什么添加 \ 也不是初始字符串。
          • 你听说过转义特殊字符吗?尝试定义 `String s = "{ "1":33 }";在Java中
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-06-17
          • 2019-02-03
          • 2014-07-20
          • 1970-01-01
          • 2018-07-16
          • 2016-06-27
          • 2011-07-24
          相关资源
          最近更新 更多