sb_269
sb_269

Reputation: 563

Android convert String to HashMap

I have a string that is something like this:

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

The structure is {"key":value}. I need to convert this to a table/HashMap so that I can fetch values based on the key.

I tried using Gson but failed. Could there be a simpler method to do it like using some serialization?

TIA

Upvotes: 3

Views: 12897

Answers (5)

Achintya Jha
Achintya Jha

Reputation: 12843

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);

}

Output:

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

Upvotes: 1

Brian Roach
Brian Roach

Reputation: 76898

You have an array of objects, each one different (it has a different field). JSON parsers are going to have problems with that when talking about deserializing it to an object. The Gson users guide specifically mentions this.

You can use Gson, but you're going to have to use one of the methods they suggest. Creating a custom deserializer that returned a Map would be fairly straightforward. You need to go through the array, get each object, then get extract the field and the value:

// 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;
    }
}

You use it via:

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

MyMap mm = gson.fromJson(jsonString, MyMap.class);

Upvotes: 0

Nikolay Kuznetsov
Nikolay Kuznetsov

Reputation: 9579

You can use this code using regex:

    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);
    }

prints:

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

Note: If you want Map<String,Integer> then change definition and use Integer.parseInt() to get integer from a String.

Upvotes: 0

Naveen
Naveen

Reputation: 1703

use this method I made:

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;
    }

use:

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());

you can also get all keys using map.keySet()

Upvotes: 8

Saurabh
Saurabh

Reputation: 7964

Write your own simple parser. Start reading each character from start, when you see a " then start treating next character start as start of key and at the occurrence of next " tak it key now at this point look for a : and then record value till you see a blank space or a }. Repeat this process again till you have read all characters in the string. This way if there are n characters then it will b solved in O(n)

Upvotes: 0

Related Questions