# asMap-implementation for Java (based on Arrays.asList)

I am always tired of the very verbose syntax in Java for creating small maps. Arrays.asList(T... a) is very convenient, and therefore I want something similar for a map.

public class MapUtils {
public static <K, V> MapBuilder<K, V> asMap(K key, V value) {
return new MapBuilder<K, V>().entry(key, value);
}

public static class MapBuilder<K, V> extends HashMap<K, V> {
public MapBuilder<K, V> entry(K key, V value) {
this.put(key, value);
return this;
}
}
}

/* Example of how to use asMap */
public class Example {
public void example() {
Map<String, String> map = MapUtil.asMap("key", "value").entry("key2", "value2");
}
}

/* Example of how the one way to create an inline Map in Java */
public class Before {
public void before() {
Map<String, String> map = new HashMap<String, String>() {{
put("key", value");
put("key2", value2");
}};
}
}


Any inputs on how to improve this implementation of MapUtils? Do you consider the asMap function a good idea, or am I too lazy to write some extra characters?

• Looks nice to me. But Landeis solution seems reasonable. :) – user unknown Jul 1 '11 at 21:33

In my opinion MapBuilder should contain a Map, not extend one. Another possible design would be to use a single call with varargs:

public class MapUtil {
public static <K,V> Map<K,V> asMap(Map.Entry<K,V>... entries) {
Map<K,V> map = new HashMap<K,V>();
for(Map.Entry<K,V> entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}

public static <K,V> Map.Entry<K,V> e(final K k, final V v) {
return new Map.Entry<K, V>() {
public K getKey() {
return k;
}
public V getValue() {
return v;
}
public V setValue(V value) {
throw new UnsupportedOperationException("Not supported");
}
};
}
}

import static very.useful.MapUtil.*;
...
Map<String, Integer> map = asMap(e("x",1),e("y",2),e("z",3));

• Well, well, but e? Just e? A bit aggressive and cryptic. – user unknown Jul 1 '11 at 21:35
• I used e for "entry", but of course this is a matter of taste. The best thing would be an operator as in Scala (here ->), but the only symbolic things we have for Java names are $ and _. Hmmm, maybe we should use $\$ for pairs, that would make at least a little bit sense. – Landei Jul 3 '11 at 8:33
• Well, or maybe entry for entry? :) – user unknown Jul 3 '11 at 14:36
• @user unknown: IMHO that would be too long. – Landei Jul 3 '11 at 18:07
• I don't like the e-function either, but I guess it is a necessary evil. – smat Jul 4 '11 at 12:29

google-collections has all about it, e.g. ImmutableMap.of(). Moreover they teach using right data structure, like true immutable collections, ordered lists etc. I really enjoyed it.

Google Collections is now part of Google Guava, and it includes ImmutableMap.Builder. With this you can do:

   static final ImmutableMap<String, Integer> WORD_TO_INT =
new ImmutableMap.Builder<String, Integer>()
.put("one", 1)
.put("two", 2)
.put("three", 3)
.build();


You can call the put(K, V) method as many times as you like. Builders are great for this kind of situation.

• Nice tip with google-collections. But it only supports up to five entries. – smat Jul 4 '11 at 12:30
• I have edited this answer with an example of using ImmutableMap.Builder, which gets around the 5 entries limit. I'm waiting for it to be peer reviewed. – Rich Jul 6 '11 at 11:26

I like Landei version, but I have also an untyped version of asMap like asMap(key,value,key,value,...). It is not typed Map, but in many cases, it fits the bill pretty well.

So

Map quickMap = asMap("prop1","val1","prop2",12,"prop3");


In this case "prop3" will have a value null.

Implementation:

static final public Map<String, Object> asMap(Object... objs) {
HashMap<String, Object> m = new HashMap<String, Object>();

for (int i = 0; i < objs.length; i += 2) {
String key = objs[i].toString();
if (i + 1 < objs.length) {
Object value = objs[i + 1];
m.put(key, value);
} else {
m.put(key, null);
}
}
return m;
}

• I wouldn't recommend this. Only the last value can contain null this way. – Yuri Sep 16 '15 at 10:16
• @yuri I am not sure, because a asMap("prop1",null,"prop2",12,"prop3"); should work, no? – Jeremy Chone Sep 17 '15 at 1:16
• sure, but it is inconsistent, which means that if you get an odd list of objects, chances are the programmer made a mistake. So I would at least implement a check on %2==0 for the argument list. And you always return something of type Map<String, Object>, maybe make a templated version? – Yuri Sep 18 '15 at 5:29