2013-06-06 3 views
1

Je me demande pourquoi il n'y a aucun moyen de construire une carte avec des valeurs dans une seule expression. Ou est-ce? Je m'attendraisJava: Construire une carte à partir d'une seule expression?

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

Je ne peux pas trouver quelque chose comme ça même dans Commons Collections.

Est-ce que j'ai manqué quelque chose dans JDK ou Commons?

+0

Goyave a que voir mon answer – fge

+0

Si vous voulez une solution JDK uniquement, vous pouvez écrire une classe simple pour cela, mais ce serait très limité. – Djon

+0

@Djon il est actuellement assez facile de mettre en œuvre un constructeur, voir ma réponse – fge

Répondre

2

Goyave a qu'avec son ImmutableMap:

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

Bonus: le nom de ImmutableMap n'est pas un mensonge;)

Notez que Il existe 5 versions de la méthode .of(), donc jusqu'à 5 paires clé/valeur. Une façon plus générique est d'utiliser un constructeur:

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

Notez, cependant: cette carte ne accepte les clés nulles ou des valeurs.

Alternativement, voici une version pauvre de ImmutableMap. Il utilise un modèle de générateur classique. Notez qu'il ne vérifie pas les valeurs NULL:

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

vous pouvez utiliser:

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

Pourquoi tout dans votre code est-il définitif? – Djon

+1

Par habitude pure.Je rends les variables finales là où elles peuvent être, les classes finales quand elles ne sont pas destinées à être héritées. – fge

+0

Je mets 'const' chaque fois que je peux en C++, mais je n'y ai jamais pensé en Java, monde étrange. – Djon

2

Essayez cette ..

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

Bon, c'est une solution valide, mais en créant une sous-classe pour chaque carte dont j'ai besoin ... –

+0

Le code ci-dessus utilise «initialisation de bloc». Pour être clair, il crée une classe anonyme dont le seul contenu est un bloc qui appellera plusieurs 'put' –

1

Il n'y a rien dans la Chambre des communes ou des collections dans le JDK. Mais vous pouvez également utiliser Guava et le code suivant:

Map<String, String> mapInstance = ImmutableMap.<String, String> builder().put("key1", "value1").put("key2", "value2").build(); 
0
  • Si vos clés et Vales sont du même type ayant alors cette méthode:

    <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; 
    } 
    

    Vous pouvez initialiser votre carte avec:

    init(new HashMap<String, String>(), "k1", "v1", "k2", "v2"); 
    
  • Si vos clés et Vales sont d'un type différent ayant alors cette méthode:

    <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; 
    } 
    

    Vous pouvez initialiser votre carte avec:

    init(new HashMap<String, Integer>(), 
        Arrays.asList("k1", "k2"), 
        Arrays.asList(1, 2)); 
    
+0

Err, 'Arrays.asList (" k1 "," k2 ")' fonctionne aussi bien – fge

+0

@fge , merci :) –

Questions connexes