web-dev-qa-db-fra.com

Comment créer une Map of String statique -> Array

J'ai besoin de créer une Map statique qui mappe une String donnée à un tableau de int 's.

En d'autres termes, j'aimerais définir quelque chose comme:

"fred" -> {1,2,5,8}
"dave" -> {5,6,8,10,11}
"bart" -> {7,22,10010}
... etc

Y at-il un moyen facile de faire cela en Java?

Et si possible, j'aimerais utiliser les constantes static pour les valeurs String et int.

EDIT: Pour clarifier ce que je voulais dire par static constantes pour les valeurs, et pour donner ce que je considère comme le code correct, voici mon premier essai avec la solution:

public final static String FRED_TEXT = "fred";
public final static String DAVE_TEXT = "dave";

public final static int ONE = 1;
public final static int TWO = 2;
public final static int THREE = 3;
public final static int FOUR = 4;

public final static HashMap<String, int[]> myMap = new HashMap<String, int[]>();
static {
    myMap.put(FRED_TEXT, new int[] {ONE, TWO, FOUR});
    myMap.put(DAVE_TEXT, new int[] {TWO, THREE});
}

Remarque, ces noms ne sont pas ce que je voudrais réellement utiliser. Ceci est juste un exemple artificiel.

13
DuncanKinnear

Vous ne} devez séparer déclaration et initialisation. Si vous savez comment faire, tout cela peut être fait en une seule ligne!

// assumes your code declaring the constants ONE, FRED_TEXT etc is before this line
private static final Map<String, int[]> myMap = Collections.unmodifiableMap(
    new HashMap<String, int[]>() {{
        put(FRED_TEXT, new int[] {ONE, TWO, FOUR});
        put(DAVE_TEXT, new int[] {TWO, THREE});
    }});

Nous avons ici une classe anonyme avec bloc d’initialisation , qui est un bloc de code s’exécutant construction après constructeur, que nous avons utilisé ici pour charger la carte.

Cette syntaxe/construction est parfois appelée à tort "initialisation double accolade" - je suppose parce qu'il y a deux accolades adjacentes - mais en réalité, rien de tel.

Les deux choses intéressantes à ce sujet sont:

  • il épouse la déclaration avec le contenu, et
  • étant donné que l'initialisation est en ligne, vous pouvez également effectuer un appel en ligne vers Collections.unmodifiableMap(), ce qui aboutit à une déclaration, une initialisation et une conversion en une ligne ordonnées en conversion non modifiable.

Si vous n'avez pas besoin/ne voulez pas que la carte soit non modifiable, laissez cet appel:

private static final Map<String, int[]> myMap = new HashMap<String, int[]>() {{
    put(FRED_TEXT, new int[] {ONE, TWO, FOUR});
    put(DAVE_TEXT, new int[] {TWO, THREE});
}};
28
Bohemian

Vous devez déclarer et initialiser votre carte statique séparément.

Voici le morceau de déclaration:

private static final Map<String,int[]> MyMap;

Voici la pièce d'initialisation:

static {
    Map<String,int[]> tmpMap = new HashMap<String,int[]>();
    tmpMap.put("fred", new int[] {1,2,5,8});
    tmpMap.put("dave", new int[] {5,6,8,10,11});
    tmpMap.put("bart", new int[] {7,22,10010});
    MyMap = Collections.unmodifiableMap(tmpMap);
}

Malheureusement, les tableaux sont toujours accessibles en écriture en Java. Vous ne pourrez pas affecter MyMap, mais vous pourrez ajouter ou supprimer des valeurs d'autres parties de votre programme qui accèdent à la carte.

8
dasblinkenlight

Par souci d'exhaustivité, il s'agit du premier résultat de Google pour "Java static define map". Dans Java 8, vous pouvez désormais le faire.

Collections.unmodifiableMap(Stream.of(
            new SimpleEntry<>("a", new int[]{1,2,3}),
            new SimpleEntry<>("b", new int[]{1,2,3}),
            new SimpleEntry<>("c", new int[]{1,2,3}))
            .collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())));

La bonne partie de ceci est que nous ne créons plus de classes anonymes avec la syntaxe à double accolade ({{ }})

Nous pouvons ensuite étendre cela avec du code pour nettoyer le modèle comme ce gars l’a fait ici http://minborgsjavapot.blogspot.ca/2014/12/Java-8-initializing-maps-in-smartest-way .html

public static <K, V> Map.Entry<K, V> entry(K key, V value) {
    return new AbstractMap.SimpleEntry<>(key, value);
}

public static <K, U> Collector<Map.Entry<K, U>, ?, Map<K, U>> entriesToMap() {
    return Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue());
}

public static <K, U> Collector<Map.Entry<K, U>, ?, ConcurrentMap<K, U>> entriesToConcurrentMap() {
    return Collectors.toConcurrentMap((e) -> e.getKey(), (e) -> e.getValue());
}

résultat final

Collections.unmodifiableMap(Stream.of(
            entry("a", new int[]{1,2,3}),
            entry("b", new int[]{1,2,3}),
            entry("c", new int[]{1,2,3}))
            .collect(entriesToMap()));

ce qui nous donnerait une carte non modifiable concurrente.

6
xori
static Map<String, int[]> map = new HashMap<>();

La carte est statique, vous pouvez y accéder sans créer d'instance de la classe dans laquelle elle est définie. Je ne sais pas ce que vous voulez dire par le fait que les clés et les valeurs sont également statiques, car cela n'a aucun sens.

1
jlordo
public class ExampleClass {
    public final static HashMap consts = new HashMap();
    static
    {
        constants.put("A", "The Letter A");
        constants.put("B", "The Letter B");
        constants.put("C", "The Letter C");
    }
    /* Rest of your class that needs to know the consts */
}
0
user2038046