JavaRush /Blog Java /Random-FR /Les 9 principales questions sur la carte en Java
Treefeed
Niveau 21

Les 9 principales questions sur la carte en Java

Publié dans le groupe Random-FR
Rappelez-vous qu'une carte est constituée de données structurées constituées d'un ensemble de paires clé-valeur et que chaque clé ne peut être utilisée qu'une seule fois dans une seule carte. Cette rubrique couvre 9 questions de base sur l'utilisation de Map en Java et ses classes implémentées. Pour plus de simplicité, j'utiliserai des généralisations dans les exemples . Par conséquent, j'écrirai simplement Map, sans spécifier le spécificateur Map. Mais vous pouvez supposer que les deux valeurs de K et V sont comparables, ce qui signifie que K étend Comparable et V étend également Comparable .Les 9 principales questions sur la carte en Java - 1

0. Conversion d'une carte en liste

En Java, l' interface Map propose trois types de collections : un ensemble de clés, un ensemble de valeurs et un ensemble de valeurs-clés. Tous peuvent être transformés en List à l'aide du constructeur ou de la méthode addAll(). L'extrait de code suivant montre comment créer une ArrayList à partir d'une carte.
// list of keys
List keyList = new ArrayList(Map.keySet());
//list of values
List valueList = new ArrayList(Map.valueSet());
//list key-value
List entryList = new ArrayList(Map.entrySet());

1. Parcourez toutes les valeurs de la carte

Parcourir chaque paire clé-valeur est la procédure de base la plus élémentaire pour parcourir une carte. En Java, chaque paire est stockée dans un champ Map appelé Map.Entry . Map.entrySet()renvoie un ensemble de valeurs-clés, donc le moyen le plus efficace de parcourir toutes les valeurs d'une carte serait :
for(Entry entry: Map.entrySet()) {
  //get the key
  K key = entry.getKey();
  //get value
  V value = entry.getValue();
}
On peut également utiliser Iterator, notamment dans les versions antérieures au JDK 1.5
Iterator itr = Map.entrySet().iterator();
while(itr.hasNext()) {
  Entry entry = itr.next();
  //get the key
  K key = entry.getKey();
  //get value
  V value = entry.getValue();
}

2. Classement de la carte par clés

L'organisation des cartes par clés est une autre procédure couramment utilisée. La première consiste à ajouter Map.Entry à la liste et à trier à l'aide d'un comparateur qui trie par valeurs.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getKey().compareTo(e2.getKey());
  }
});
Une autre façon : utilisez SortedMap , qui, en plus, organise également ses clés dans l'ordre. Mais toutes les clés doivent inclure Comparable ou être acceptées par le comparateur. L'une des classes implémentées SortedMapest TreeMap . Son constructeur accepte un comparateur. Le code suivant montre comment transformer un code normal Mapen un code ordonné.
SortedMap sortedMap = new TreeMap(new Comparator() {

  @Override
  public int compare(K k1, K k2) {
    return k1.compareTo(k2);
  }

});
sortedMap.putAll(Map);

3. Trier la carte par valeurs

Ajouter une carte à la liste puis la trier fonctionne dans ce cas, mais cette fois, vous devez utiliser Entry.getValue(). Le code ci-dessous est presque le même qu’avant.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getValue().compareTo(e2.getValue());
  }

});
On peut toujours l'utiliser SortedMapdans ce cas, mais seulement si les valeurs sont uniques. Dans ce cas, vous pouvez transformer la paire clé-valeur en clé-valeur. Cette solution présente de sérieuses limites et n’est pas recommandée par moi.

4. Initialisation d'une carte statique/immuable

Lorsque vous souhaitez qu'une Map reste immuable, un bon moyen consiste à la copier dans une Map immuable. Cette technique de programmation défensive vous aidera à créer une carte qui est non seulement sûre à utiliser, mais également thread-safe. Pour initialiser une Map statique/immuable, nous pouvons utiliser un initialiseur static(voir ci-dessous). Le problème avec ce code est que même si Map est déclaré comme static final, nous pouvons toujours travailler avec lui après l'initialisation, par exemple Test.Map.put(3,"three");. Ce n'est donc pas une véritable immuabilité. Pour créer une Map immuable à l'aide d'un initialiseur statique, nous avons besoin d'une classe super anonyme, que nous ajouterons à la Map immuable lors de la dernière étape d'initialisation. Veuillez regarder la deuxième partie du code. Lorsqu'une UnsupportedOperationException sera levée si vous exécutez Test.Map.put(3,"three");.
public class Test {

  private static final Map Map;
  static {
    Map = new HashMap();
    Map.put(1, "one");
    Map.put(2, "two");
  }
}
public class Test {

  private static final Map Map;
  static {
    Map aMap = new HashMap();
    aMap.put(1, "one");
    aMap.put(2, "two");
    Map = Collections.unmodifiableMap(aMap);
  }
}
La bibliothèque Guava prend également en charge diverses manières d'initialiser des collections statiques et immuables. Pour en savoir plus sur les avantages de l'utilitaire de collections immuables de Guava, consultez la section Collections immuables dans le guide pratique de Guava .

5. Différence entre HashMap, TreeMap et Hashtable

Il existe trois implémentations principales de l'interface Map en Java : HashMap , TreeMap et Hashtable . Les principales différences sont les suivantes :
  • Ordre de passage . HashMap et HashTable ne garantissent pas l'ordre de la carte ; ils ne garantissent notamment pas que la commande restera la même dans le temps. Mais TreeMapil ordonnera toutes les valeurs dans « l'ordre naturel » des clés ou par un comparateur.
  • Paires clé-valeur valides. HashMappermet d'avoir une clé nulle et une valeur nulle. HashTablen'autorise pas une clé nulle ou une valeur nulle. Si TreeMapl'ordre naturel est utilisé ou si le comparateur n'autorise pas une clé nulle, une exception sera levée.
  • Synchronisation . Seulement HashTablesynchronisé, les autres ne le sont pas. Mais, "si une implémentation thread-safe n'est pas nécessaire, il est recommandé d'utiliser " HashMapà la place HashTable.
Comparaison plus détaillée
.                       | HashMap | HashTable | TreeMap
-------------------------------------------------------

Упорядочивание          |нет      |нет        | да
null в ключ-meaning    | да-да   | нет-нет   | нет-да
синхронизировано        | нет     | да        | нет
производительность      | O(1)    | O(1)      | O(log n)
воплощение              | корзины | корзины   | красно-чёрное дерево
En savoir plus sur la relation HashMap vs. TreeMap contre. Table de hachage vs. LinkedHashMap .

6. Carte avec recherche/affichage inversée

Parfois, nous avons besoin d'un ensemble de paires clé-clé, ce qui signifie que les valeurs sont aussi uniques que les clés (un modèle un-à-un). Cette cohérence 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 Map bidirectionnelle , qui n'est malheureusement pas prise en charge par le JDK. Apache Common Collections et Guava proposent des implémentations de cartes bidirectionnelles appelées respectivement BidiMap et BiMap. Les deux introduisent une contrainte qui impose un mappage 1:1 entre les clés et les valeurs.

7. Copie superficielle de la carte

Presque toutes, sinon toutes, les cartes en Java contiennent un constructeur de copie pour une autre carte. Mais la procédure de copie n'est pas synchronisée. Ce qui signifie que lorsqu'un thread copie une Map, un autre thread peut modifier sa structure. Pour éviter une désynchronisation soudaine de la copie, l'un d'eux doit être utilisé dans un tel cas Collections.synchronizedMap().
Map copiedMap = Collections.synchronizedMap(Map);
Une autre façon intéressante de copier superficiellement consiste à utiliser le fichier clone(). Mais ce n'est PAS recommandé même par le créateur du framework de collections Java, Joshua Bloch. Dans le débat " Copy Constructor vs. Cloning ", il prend position : Citation : " Je propose souvent une méthode de clonage public dans des classes concrètes parce que les gens s'attendent à ce qu'elles soient là. ... c'est dommage que le clonage soit cassé, mais il s'est produit... Le clonage est un point faible et je pense que les gens devraient être avertis de ses limites. Pour cette raison, je ne vous montre même pas comment utiliser la méthode clone()pour copier Map

8. Créez une carte vide

Si Mapimmuable, utilisez :
Map = Collections.emptyMap();
Ou utilisez tout autre mode de réalisation. Par exemple:
Map = new HashMap();
FIN
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION