Search code examples
javadictionaryconstruct

Java: Constructing a Map from a single expression?


I wonder why there's no way to construct a map with values in a single expression. Or is it? I'd expect

new HashMap().add(key, value).add(key, value)...;

I can't find anything like that even in Commons Collections.

Did I miss some way in JDK or Commons?


Solution

  • Guava has that with its ImmutableMap:

    final Map<Foo, Bar> map = ImmutableMap.of(foo1, bar1, foo2, bar2, etc, etc);
    

    Bonus: ImmutableMap's name is not a lie ;)

    Note that there are 5 versions of the .of() method, so up to 5 key/value pairs. A more generic way is to use a builder:

    final Map<Foo, Bar> map = ImmutableMap.<Foo, Bar>builder()
        .put(foo1, bar1)
        .put(foo2, bar2)
        .put(foo3, bar3)
        .put(etc, etc)
        .build();
    

    Note, however: this map does not accept null keys or values.

    Alternatively, here is a poor man's version of ImmutableMap. It uses a classical builder pattern. Note that it does not check for nulls:

    public final class MapBuilder<K, V>
    {
        private final Map<K, V> map = new HashMap<K, V>();
    
        public MapBuilder<K, V> put(final K key, final V value)
        {
            map.put(key, value);
            return this;
        }
    
        public Map<K, V> build()
        {
            // Return a mutable copy, so that the builder can be reused
            return new HashMap<K, V>(map);
        }
    
        public Map<K, V> immutable()
        {
            // Return a copy wrapped into Collections.unmodifiableMap()
            return Collections.unmodifiableMap(build());
        }
    }
    

    Then you can use:

    final Map<K, V> map = new MapBuilder<K, V>().put(...).put(...).immutable();