Pregunta

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?

¿Fue útil?

Solución

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();

Otros consejos

Try this..

  Map<String, Integer> map = new HashMap<String, Integer>()
{{
     put("One", 1);
     put("Two", 2);
     put("Three", 3);
}};

There is nothing in Commons Collections or in the JDK. But you could alternatively use Guava and the following code:

Map<String, String> mapInstance = ImmutableMap.<String, String> builder().put("key1", "value1").put("key2", "value2").build();
  • If your your keys and vales are of the same type then having such method:

    <K> Map<K, K> init(Map<K, K> map, K... args) {
        K k = null;
        for(K arg : args) {
            if(k != null) {
                map.put(k, arg);
                k = null;
            } else {
                k = arg;
            }
        }
        return map;
    }
    

    You can initialize your map with:

    init(new HashMap<String, String>(), "k1", "v1", "k2", "v2");
    
  • If your your keys and vales are of a different type then having such method:

    <K, V> Map<K, V> init(Map<K, V> map, List<K> keys, List<V> values) {
        for(int i = 0; i < keys.size(); i++) {
            map.put(keys.get(i), values.get(i));
        }
        return map;
    }
    

    You can initialize your map with:

    init(new HashMap<String, Integer>(), 
         Arrays.asList("k1", "k2"), 
         Arrays.asList(1, 2));
    
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top