J'écris un programme simple pour convertir un nombre en un mot représentant ce nombre (13 => "treize").
Je réalise que je pourrais obtenir certains mots avec un tableau de chaînes constant comme ceci:
private static final String[] tensNames = {"", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" };
... et y accéder avec l'index, mais je voulais l'essayer avec un HashMap comme ceci:
final HashMap<Integer, String> tensNumberConversion = new HashMap<Integer, String>();
tensNumberConversion.put(2, "twenty");
tensNumberConversion.put(3, "thirty");
tensNumberConversion.put(4, "forty");
tensNumberConversion.put(5, "fifty");
tensNumberConversion.put(6, "sixty");
tensNumberConversion.put(7, "seventy");
tensNumberConversion.put(8, "eighty");
tensNumberConversion.put(9, "ninety");
Un enseignant m'a demandé de faire ces constantes. Le HashMap peut-il être une constante? En tant que débutant, la relation entre les termes "constante", "statique" et "final" n'était pas tout à fait claire et ce qui fait exactement une constante. (statique seule? finale seule? finale statique ensemble?).
J'ai essayé de rendre le Hashmap final statique privé mais IntelliJ m'a donné une erreur (le modificateur "privé" n'est pas autorisé ici ... de même pour "statique").
Cependant, il compile à partir de mon terminal sans erreur. Si un HashMap peut être une constante, est-ce la bonne façon de le déclarer? Merci!
Il y a deux aspects ici:
Donc, pour arriver à une vraie carte "constante", vous optez pour ceci:
Tout d'abord, vous créez une carte ordinaire contenant toutes les valeurs souhaitées.
Ensuite, vous utilisez Collections.unmodifiableMap()
afin de créer une carte qui ne peut plus être modifiée.
La seule chose à laquelle il faut prêter attention: vous devez vous assurer de ne pas laisser fuir une référence à l'objet de la carte d'origine, car cette carte immuable est simplement une enveloppe autour de cette carte initiale. Vous pouvez le faire dans une méthode d'assistance peu, par exemple.
Si vous demandez: existe-t-il un moyen d'écrire une déclaration de carte sous une "forme littérale" spéciale (comme pour les tableaux) - il n'y en a pas. Eh bien, vous pouvez changer cette méthode d'assistance pour prendre Object ...
en tant que paramètre; et ensuite vous passeriez en revue ces paramètres, l’un est un nombre, l’autre une chaîne, et l’utiliser pour remplir la carte. Vous pouvez donc invoquer la méthode avec une seule séquence de valeurs. Mais ça ne vaut probablement pas la peine ...
Une mise à jour rapide: Java9 a ajouté diverses méthodes d’assistance statique qui vous permettent d’écrire des cartes de façon "littérale", voir ici par exemple.
Oui, ça peut être une constante. Vous devez déclarer votre instance HashMap
comme suit:
class <class name> {
private static final HashMap<Integer, String> tensNumberConversion = new HashMap<>();
static {
tensNumberConversion.put(2, "twenty");
tensNumberConversion.put(3, "thirty");
tensNumberConversion.put(4, "forty");
tensNumberConversion.put(5, "fifty");
tensNumberConversion.put(6, "sixty");
tensNumberConversion.put(7, "seventy");
tensNumberConversion.put(8, "eighty");
tensNumberConversion.put(9, "ninety");
}
}
Cependant, il ne s'agit que d'une référence constante. Bien que vous ne puissiez pas réaffecter tensNumberConversion
à autre chose, vous pouvez toujours modifier le contenu de votre carte ultérieurement au moment de l'exécution:
tensNumberConversion = new HashMap<>(); // won't compile
tensNumberConversion.put(9, "one"); // succeeds
Si vous souhaitez également que le contenu de votre carte soit constant, vous devez envelopper la HashMap
dans une carte non modifiable:
class <class name> {
private static final Map<Integer, String> tensNumberConversion = initMap();
private static Map<Integer, String> initMap() {
Map<Integer, String> map = new HashMap<>();
map.put(2, "twenty");
map.put(3, "thirty");
map.put(4, "forty");
map.put(5, "fifty");
map.put(6, "sixty");
map.put(7, "seventy");
map.put(8, "eighty");
map.put(9, "ninety");
return Collections.unmodifiableMap(map);
}
}
Juste un BTW, avec Java 9, il existe des méthodes statiques dans l'interface Map
pour créer des cartes immuables avec un certain nombre d'entrées comme:
Map<String,String> m = Map.of("k1", "v1",
"K2", "v2");
Ou si plus de 10 entrées sont nécessaires:
import static Java.util.Map.entry;
Map<String, String> m = Map.ofEntries(
entry("k1", "v1"), entry("k2", "v2"), …);
J'ai en quelque sorte manqué la forme la plus facile pour l'initialisation directe de HashMap ici
private static final Map<Integer, String> tensNumberConversion_internal = new HashMap<Integer, String>()
{
{
put(2, "twenty");
put(3, "thirty");
put(4, "forty");
put(5, "fifty");
put(6, "sixty");
put(7, "seventy");
put(8, "eighty");
put(9, "ninety");
};
};
et comme pour le rendre immuable, vous avez déjà Collections.unmodifiableMap
de la réponse acceptée donc
public static final Map<Integer, String> tensNumberConversion = Collections.unmodifiableMap(tensNumberConversion_internal);
ils doivent être créés dans cet ordre de cours;)
Au lieu d'utiliser le compostage pour obtenir une HashMap constante, vous pouvez utiliser l'héritage pour hériter d'une nouvelle classe de HashMap, puis remplacer la méthode HashMap.put () pour afficher un message d'échec approprié ...
class MyMap extends Java.util.HashMap{
@Override
public V put (K key, V value){
System.out.println("Operation Not Supported");
return null;
}
}
Notez que ce n’est pas la seule méthode mais l’une des nombreuses méthodes possibles.