Search code examples
javahashmap

Split string into key-value pairs


I have a string like this:

pet:cat::car:honda::location:Japan::food:sushi

Now : indicates key-value pairs while :: separates the pairs. I want to add the key-value pairs to a map.

I can achieve this using:

Map<String, String> map = new HashMap<String, String>();
String test = "pet:cat::car:honda::location:Japan::food:sushi";
String[] test1 = test.split("::");

for (String s : test1) {
    String[] t = s.split(":");
    map.put(t[0], t[1]);
}

for (String s : map.keySet()) {
    System.out.println(s + " is " + map.get(s));
}

But is there an efficient way of doing this?


I feel the code is inefficient because I have used 2 String[] objects and called the split function twice. Also, I am using t[0] and t[1] which might throw an ArrayIndexOutOfBoundsException if there are no values.


Solution

  • You could do a single call to split() and a single pass on the String using the following code. But it of course assumes the String is valid in the first place:

        Map<String, String> map = new HashMap<String, String>();
        String test = "pet:cat::car:honda::location:Japan::food:sushi";
    
        // split on ':' and on '::'
        String[] parts = test.split("::?");
    
        for (int i = 0; i < parts.length; i += 2) {
            map.put(parts[i], parts[i + 1]);
        }
    
        for (String s : map.keySet()) {
            System.out.println(s + " is " + map.get(s));
        }
    

    The above is probably a little bit more efficient than your solution, but if you find your code clearer, then keep it, because there is almost zero chance such an optimization has a significant impact on performance, unless you do that millions of times. Anyway, if it's so important, then you should measure and compare.

    EDIT:

    for those who wonder what ::? means in the above code: String.split() takes a regular expression as argument. A separator is a substring that matches the regular expression. ::? is a regular expression which means: 1 colon, followed by 0 or 1 colon. It thus allows considering :: and : as separators.