PeterMmm
PeterMmm

Reputation: 24630

Convert string representing key-value pairs to Map

How can I convert a String into a Map:

Map m = convert("A=4 H=X PO=87"); // What's convert?
System.err.println(m.getClass().getSimpleName()+m);

Expected output:

HashMap{A=4, H=X, PO=87}

Upvotes: 45

Views: 123850

Answers (8)

Volo Myhal
Volo Myhal

Reputation: 144

Let me propose another way for specific case when you have key-value pairs in different lines: to use Java's built-in Properties class:

Properties props = new Properties();
props.load(new StringReader(s));

BENEFITS:

  • short
  • for any Java version
  • gives you a ready-to-use Map<Object, Object> also supplying handy String props.getProperty(String) method
  • StringReader has built-in 8k buffer (you may adjust buffering on mega input)
  • steady against different newline characters
  • you may base on defaults Map with new Properties(defaultsMap)

WARNINGS (could be virtue or vice):

  • has special parsing rules for '.properties' format (you may want to peek inside Properties class to learn more):
    • trims spaces/tabs from keys/values
    • has special-meaning characters:
      • !,# at beginning of line is comment
      • = or : is key-value separator
      • \ is used as escape character for unicode/special chars. For example, you may want to prepare your string with s = s.replace("\\", "\\\\");
  • resulting Map is based on HashTable having synchronization unneeded in most cases

Upvotes: 1

Daniel Kaplan
Daniel Kaplan

Reputation: 67350

There is no need to reinvent the wheel. The Google Guava library provides the Splitter class.

Here's how you can use it along with some test code:

package com.sandbox;

import com.google.common.base.Splitter;
import org.junit.Test;

import java.util.Map;

import static org.junit.Assert.assertEquals;

public class SandboxTest {

    @Test
    public void testQuestionInput() {
        Map<String, String> map = splitToMap("A=4 H=X PO=87");
        assertEquals("4", map.get("A"));
        assertEquals("X", map.get("H"));
        assertEquals("87", map.get("PO"));
    }

    private Map<String, String> splitToMap(String in) {
        return Splitter.on(" ").withKeyValueSeparator("=").split(in);
    }

}

Upvotes: 63

Marsellus Wallace
Marsellus Wallace

Reputation: 18601

Java 8 to the rescue!

import static java.util.stream.Collectors.*;

Map<String, String> result = Arrays.stream(input.split(" "))
    .map(s -> s.split("="))
    .collect(Collectors.toMap(
        a -> a[0],  //key
        a -> a[1]   //value
    ));

NOTE: Assuming no duplicates. Otherwise look into the 3rd 'mergeFunction' argument.

Upvotes: 31

Arun Shankar
Arun Shankar

Reputation: 2295

private HashMap<String, String> convert(String str) {
    String[] tokens = str.split("&");
    HashMap<String, String> map = new HashMap<String, String>();
    for(int i=0;i<tokens.length;i++)
    {
        String[] strings = tokens[i].split("=");
        if(strings.length==2)
         map.put(strings[0], strings[1].replaceAll("%2C", ","));
    }

    return map;
}

Upvotes: 0

akansha aggarwal
akansha aggarwal

Reputation: 1

String elementType = StringUtility.substringBetween(elementValue.getElementType(), "{", "}");
Map<String, String>  eleTypeMap = new HashMap<String, String>();
StringTokenizer token = new StringTokenizer(elementType, ",");
while(token.hasMoreElements()){
    String str = token.nextToken();
    StringTokenizer furtherToken = new StringTokenizer(str,"=");
    while(furtherToken.hasMoreTokens()){
        eleTypeMap.put(furtherToken.nextToken(), furtherToken.nextToken());
    }
}

Upvotes: -1

Denys Vasylenko
Denys Vasylenko

Reputation: 2143

public static Map<String, String> splitToMap(String source, String entriesSeparator, String keyValueSeparator) {
    Map<String, String> map = new HashMap<String, String>();
    String[] entries = source.split(entriesSeparator);
    for (String entry : entries) {
        if (!TextUtils.isEmpty(entry) && entry.contains(keyValueSeparator)) {
            String[] keyValue = entry.split(keyValueSeparator);
            map.put(keyValue[0], keyValue[1]);
        }
    }
    return map;
}

And now you can use it for different types of entries/key-values separators, just like this

Map<String, String> responseMap = splitToMap(response, " ", "=");

Upvotes: 7

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382132

You don't need a library to do that. You just need to use StringTokenizer or String.split and iterate over the tokens to fill the map.

The import of the library plus its settings would be almost as big as the three lines of code needed to do it yourself. For example :

public static Map<String, String> convert(String str) {
    String[] tokens = str.split(" |=");
    Map<String, String> map = new HashMap<>();
    for (int i=0; i<tokens.length-1; ) map.put(tokens[i++], tokens[i++]);
    return map;
}

Note that in real life, the validation of the tokens and the string, highly coupled with your business requirement, would probably be more important than the code you see here.

Upvotes: 23

kachanov
kachanov

Reputation: 2755

split String by " ", then split each item by "=" and put pairs into map. Why would you need "library" for such elementary thing?

Upvotes: 4

Related Questions