I am looking for the opposite of map joiner in google collections. is there something like this, and if not why?
EDIT: here is an example how I wish it would be:
Map<String,String> myMap = Splitter.on(",").keyValueSeparator("=").split("k1=v1,k2=v2");
EDIT: I opened a request and it was implemented. will be available in guava R10.
Here's a class Maps2
that provides a method
Map<String, String> mapSequence(String)
It also provides two overloaded methods where you can change the delimiters that are used a) between keys and values (default: =
) and b) between entries (default: ,
). Guava classes like Splitter
and Iterables
are used internally to do the work. The returned map is a LinkedHashMap
, so entry order is preserved.
public final class Maps2{
public static final String DEFAULT_ENTRY_DELIMITER = ",";
public static final String DEFAULT_KEYVALUE_DELIMITER = "=";
private Maps2(){}
public static Map<String, String> mapSequence(final String sequence){
return mapSequence(sequence, DEFAULT_KEYVALUE_DELIMITER);
}
public static Map<String, String> mapSequence(final String sequence,
final String keyValueDelim){
return mapSequence(sequence, keyValueDelim, DEFAULT_ENTRY_DELIMITER);
}
public static Map<String, String> mapSequence(final String sequence,
final String keyValueDelim, final String entryDelim){
final Splitter entrySplitter = Splitter.on(entryDelim)
.trimResults();
final Splitter keyValueSplitter = Splitter.on(keyValueDelim)
.trimResults();
final Map<String, String> map = Maps.newLinkedHashMap();
for(final String token : entrySplitter.split(sequence)){
final String[] items =
Iterables.newArray(
keyValueSplitter.split(token), String.class);
if(items.length != 2){
throw new IllegalArgumentException(
"Map String not well-formed");
}
map.put(items[0], items[1]);
}
return map;
}
}
Test code:
public static void main(final String[] args){
// note the randomly spread whitespace in the test code,
// also the last entry has no value.
// using Splitter().trimResults() we can handle junk like that
final Map<String, String> map = Maps2.mapSequence("k1=v1 ,k2=v2, k3 =");
System.out.println(map);
}
Output:
{k1=v1, k2=v2, k3=}
I think there no such a feature in guava. For me the reason is that the entry String can have many formats, so that you have to create your own "parser" for your own format. An (ugly) alternative could be this one, if you can modify the format of your entry string:
final String toSplit = "k1=v1" + getProperty("line.separator") + "k2=v2";
final Properties properties = new Properties();
properties.load(new ByteArrayInputStream(toSplit.getBytes(Charsets.UTF_8)));
Maps.fromProperties(properties);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With