Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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?

share|improve this question
Looks nice to me. But Landeis solution seems reasonable. :) – user unknown Jul 1 '11 at 21:33

2 Answers

up vote 5 down vote accepted

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));
share|improve this answer
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
1  
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.

share|improve this answer
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.