Je souhaite ajouter des valeurs à un HashMap, qui seraient utilisées par les méthodes du même classe. Jai deux solutions:

  1. Ajout de toutes les valeurs avec static
  2. Lorsque la première méthode est appelée, ajoutez les valeurs

Solution n ° 1:

private static Map<Character, String> codes = new HashMap<>(); static { codes.put("A", ".-"); codes.put("B", "-..."); codes.put("C", "-.-."); codes.put("D", "-.."); codes.put("E", "."); codes.put("F", "..-."); // ... } 

Solution n ° 2:

boolean methodIsCalled = false; public static char decode(String s) { if(!methodIsCalled) { addValues(); methodIsCalled = true; } // ... } private static void addValues() { codes.put("A", ".-"); codes.put("B", "-..."); codes.put("C", "-.-."); codes.put("D", "-.."); codes.put("E", "."); codes.put("F", "..-."); // ... } 

Laquelle est la plus efficace? Quelle est la meilleure pratique?

Commentaires

  • Pourquoi mettez-vous cela dans un HashMap en premier lieu? Pourquoi pas un tableau de 26 chaînes?
  • Comment un tableau de 26 chaînes résout-il ce problème? En particulier, comment faire la cartographie? Vous avez la conversion implicite de A – > 0, B – > 0, …, à lesprit?
  • @Ali un tableau final gère limmuabilité et linitalisation. A- > 0, B- > 1 le fait assez bien en évitant la plupart des autres problèmes dautres bibliothèques nécessaires, des blocs statiques supplémentaires ou constructeurs. Il ' est clair et raisonnable.
  • @MichaelT Peut-être pour cet exemple particulier, étant donné que lutilisateur veut avoir un mappage pour le code morse, un tableau de String de taille 26 est bien, cependant, ce nest pas une solution générale. Ma réponse était vers une solution générale, pas celle-ci en particulier. Dans de nombreux cas, le domaine est si grand que nous ne pouvons pas utiliser de mappage direct vers des entiers et nous devons utiliser un hashmap.
  • @MichaelT btw, un tableau nest immuable que par taille, mais vous pouvez changer lun de ses éléments. a [0] = " new val ".

Réponse

Votre solution 1 peut être problématique, car le hashmap est statique et ne sera initialisé quune seule fois, et est partagé par toutes les instances de votre classe. Est-ce votre comportement prévu ou voulez-vous que chaque instance ait sa propre carte? Si vous navez quune seule carte, je suggérerais de passer lensemble au constructeur au lieu den utiliser une statique, par exemple:

public class Data { private final Map<Character, String> codes; public Data(Map<Character, String> codes) { this.codes = codes} } 

Votre solution 2 ajoute la surcharge de linitialisation paresseuse de lensemble, chaque fois que vous en avez besoin, et ajoute la vilaine vérification methodIsCalled à la logique de votre programme. Je pense quinitialiser la carte dans le constructeur est une meilleure option.

public class Data { private final Map<Character, String> codes; public Data() { this.codes = new HashMap<>(); codes.put("A", ".-"); codes.put("B", "-..."); codes.put("C", "-.-."); codes.put("D", "-.."); codes.put("E", "."); codes.put("F", "..-."); } } 

Lautre question à laquelle vous devez répondre est que si vous changez les valeurs de cette hashmap plus tard ou non. Si vous ne le modifiez pas, vous feriez mieux de rechercher des hashMaps immuables. Une option consiste à utiliser Collections.unmodifiableMap (map).

Vous pouvez également utiliser les bibliothèques Google Guava pour vous permettre d’initialiser une carte dans une ligne et obtenez une carte immuable:

ImmutableMap.<Character, String>builder() .put("A", ".-") .put("B", "-...") .put("C", "-.-.") .put("D", "-..") .put("E", ".") .put("F", "..-.") .build(); 

Réponse

Rien ne peut battre ImmutableMap de Guava avec sa consommation de mémoire optimisée, mais voici une paire de solutions pures:

/* Name of the class has to be "Main" only if the class is public. */ class Ideone { private static final Map<Character, String> codes1; static { Map<Character, String> temp= new HashMap<Character, String>(); temp.put("A", ".-"); temp.put("B", "-..."); temp.put("C", "-.-."); temp.put("D", "-.."); temp.put("E", "."); temp.put("F", "..-."); // ... codes1 = Collections.unmodifiableMap(temp); } private static final Map<Character, String> codes2 = Collections.unmodifiableMap(new HashMap<Character, String>() { { put("A", ".-"); put("B", "-..."); put("C", "-.-."); put("D", "-.."); put("E", "."); put("F", "..-."); // ... } }); } 

Réponse

Si vous ninsistez pas sur une initialisation paresseuse (et pour une petite carte non croissante de 26 éléments, vous ne devriez pas « t), alors pourquoi ne pas optimiser la lisibilité? Jutiliserais toujours quelque chose comme

private static Map<Character, String> codes = newMap( "A", ".-", "B", "-...", "C", "-.-.", ... ); 

(avec une fonction dassistance correctement définie newMap).

Commentaires

  • Pouvez-vous même écrire newMap avec des packs de paramètres?
  • @ VF1 Vous pouvez, si vous le définissez comme une fonction générique avec varargs .

Réponse

Dans ces cas, je suppose que la question ne concerne pas la méthode efficace – mais plutôt quand ont réellement besoin de cette carte initialisée et prête.

dans le cas de linitialisation statique – au moment où la classe est chargée

votre approche de chargement différé peut être nécessaire si vous devez définir « énorme « map, et disons souvent que ces valeurs proviennent dune source coûteuse (cest-à-dire à travers le réseau), même dans ce cas, vous naurez peut-être pas besoin dun indicateur externe.

Collection.isEmpty () vous dira si cela a déjà été initialisé ou non (à condition, bien sûr, quau moins une valeur soit là pour être initialisée)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *