JavaRush /Blog Java /Random-FR /Réponses aux questions les plus fréquentes sur l'interfac...

Réponses aux questions les plus fréquentes sur l'interface Map

Publié dans le groupe Random-FR
Bonjour! Aujourd'hui, nous allons donner des réponses aux questions les plus courantes sur Map, mais rappelons-nous d'abord de quoi il s'agit. Réponses aux questions les plus fréquentes sur l'interface Map - 1Une carte est une structure de données qui contient un ensemble de paires clé-valeur. Sa structure de données ressemble à un dictionnaire, c'est pourquoi on l'appelle souvent ainsi. En même temps, Map est une interface , et dans le jdk standard, elle contient les principales implémentations : Hashmap, LinkedHashMap, Hashtable, TreeMap. L’implémentation la plus utilisée est Hashmap, nous l’utiliserons donc dans nos exemples. Voici à quoi ressemble la création et le remplissage standard d'une carte :
Map<Integer, String> map = new HashMap<>();
map.put(1, "string 1");
map.put(2, "string 2");
map.put(3, "string 3");
Et voici comment obtenir les valeurs par clé :
String string1 = map.get(1);
String string2 = map.get(2);
String string3 = map.get(3);
Si tout ce qui précède est clair, passons à nos réponses aux questions courantes !

0. Comment parcourir toutes les valeurs de la carte

L'itération sur les valeurs est l'opération la plus courante que vous effectuez avec des cartes. Toutes les paires clé-valeur sont stockées dans l'interface interne Map.Entry et pour les obtenir, vous devez appeler le fichier entrySet(). Il renvoie un ensemble de paires qui peuvent être parcourues en boucle :
for(Map.Entry<Integer, String> entry: map.entrySet()) {
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

Или используя итератор:
Iterator<Map.Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
   Map.Entry<Integer, String> entry =  itr.next();
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

1. Comment convertir une carte en liste

L'interface Map dispose de 3 méthodes qui renvoient une liste d'éléments :
  • keySet() - renvoie un ensemble de clés ;
  • valeurs() - renvoie une collection de valeurs ;
  • EntrySet() - renvoie un ensemble d'ensembles clé-valeur.
Si vous regardez les constructeurs de la classe ArrayList, vous remarquerez qu'il existe un constructeur avec un argument de type Collection. Puisque Set est un descendant de Collection, les résultats de toutes les méthodes ci-dessus peuvent être transmis au constructeur de la classe ArrayList. Nous allons donc créer de nouvelles listes et les remplir avec des valeurs provenant Mapde :
// key list
List<Integer> keyList = new ArrayList<>(map.keySet());
// value list
List<String> valueList = new ArrayList<>(map.values());
// key-value list
List<Map.Entry<Integer, String>> entryList = new ArrayList<>(map.entrySet());

2. Comment trier les clés de la carte

Le tri des cartes est également une opération assez courante en programmation. Tu peux le faire de plusieurs façons:
  1. Mettez Map.Entry dans une liste et triez-la à l’aide de Comparator .

    Dans le comparateur nous comparerons uniquement les clés de paires :

    List> list = new ArrayList(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
       @Override
       public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
           return o1.getKey() - o2.getKey();
       }
    });
    

    Si vous comprenez les lambdas, cette entrée peut être considérablement raccourcie :

    Collections.sort(list, Comparator.comparingInt(Map.Entry::getKey));
  2. Utilisez SortedMap, ou plus précisément, son implémentation TreeMap, qui prend un Comparator dans son constructeur. Ce comparateur sera appliqué aux clés de la map, les clés doivent donc être des classes qui implémentent l'interface Comparable:

    SortedMap<Integer, String> sortedMap = new TreeMap<>(new Comparator<Integer>() {
       @Override
       public int compare(Integer o1, Integer o2) {
           return o1 - o2;
       }
    });

    Et bien sûr, tout peut être réécrit en utilisant des lambdas :

    SortedMap<Integer, String> sortedMap = new TreeMap<>(Comparator.comparingInt(o -> o));

    Contrairement à la première méthode, utilisant SortedMap, nous stockerons toujours les données sous forme triée.

3. Comment trier les valeurs de la carte

Ici, vous devez utiliser une approche similaire à la première pour les clés - obtenez une liste de valeurs et triez-les dans la liste :
List <Map.Entry<Integer, String>> valuesList = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
   @Override
   public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
       return o1.getValue().compareTo(o2.getValue());
   }
});
Et le lambda pour cela ressemble à ceci :
Collections.sort(list, Comparator.comparing(Map.Entry::getValue));

4. Quelle est la différence entre HashMap, TreeMap et Hashtable

Comme mentionné précédemment, il existe 3 implémentations principales de l'interface Map. Chacun d'eux a ses propres caractéristiques :
  1. Ordre des éléments. HashMapet Hashtablene garantissons pas que les éléments seront stockés dans l'ordre dans lequel ils ont été ajoutés. De plus, ils ne garantissent pas que l’ordre des éléments ne changera pas dans le temps. À son tour, TreeMapil garantit le stockage des éléments dans l’ordre dans lequel ils ont été ajoutés ou conformément à un comparateur donné.

  2. Valeurs valides. HashMappermet d'avoir une clé et une valeur nulle, HashTablenon. TreeMap ne peut utiliser des valeurs nulles que si le comparateur le permet. Sans utiliser de comparateur (en stockant les paires dans l'ordre dans lequel elles ont été ajoutées), null n'est pas autorisé.

  3. Synchronisation. Seulement HashTablesynchronisé, les autres ne le sont pas. Si la carte n'est pas accessible par différents threads, il est recommandé d'utiliser HashMap au lieu de HashTable.

Et une comparaison générale des implémentations :
Carte de hachage Table de hachage ArbreCarte
Ordre des éléments Non Non Oui
null comme valeur Oui Non Pas vraiment
Sécurité du fil Non Oui Non
Complexité algorithmique de la recherche d'éléments O(1) O(1) O (log n)
Structure des données sous le capot table de hachage table de hachage arbre rouge-noir

5. Comment créer une carte bidirectionnelle

Parfois, il devient nécessaire d'utiliser une structure de données dans laquelle les clés et les valeurs seront uniques, c'est-à-dire que la carte contiendra des paires clé-clé. Cette structure de données vous permet de créer une « vue/recherche inversée » sur la carte. Autrement dit, nous pouvons trouver une clé par sa valeur. Cette structure de données est appelée une carte bidirectionnelle, qui, malheureusement, n'est pas prise en charge par le JDK. Mais heureusement, son implémentation se trouve dans les bibliothèques Apache Common Collections ou Guava. Là, il s'appelle respectivement BidiMap et BiMap. Ces implémentations imposent des restrictions sur l'unicité des clés et des valeurs. Cela crée une relation individuelle.

6. Comment créer une carte vide

Il existe deux manières de créer une carte vide :
  1. Initialisation normale de l'objet :

    Map<Integer, String> emptyMap = new HashMap<>();
  2. Création d'une carte vide immuable :

    Map<Integer, String> emptyMap =  Collections.emptyMap();
Lorsque nous essayons d'ajouter des données à une telle carte, nous recevrons : UnsupportedOperationExceptionexception. Dans cet article, nous avons examiné les questions les plus courantes que vous pourriez vous poser lors de l'utilisation de l'interface Map.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION