Un Collection
- parfois appelé conteneur - est simplement un objet qui regroupe plusieurs éléments en une seule unité. Collection
s sont utilisés pour stocker, récupérer, manipuler et communiquer des données agrégées. Un cadre de collections W est une architecture unifiée pour représenter et manipuler des collections.
Le HashMap
JDK1.2
et Hashtable JDK1.0
, les deux sont utilisés pour représenter un groupe d'objets qui sont représentés par <Key, Value>
paire. Chaque <Key, Value>
paire est appelée Entry
objet. La collection d'entrées est référencée par l'objet de HashMap
et Hashtable
. Les clés d'une collection doivent être uniques ou distinctives. [car ils sont utilisés pour récupérer une valeur mappée une clé particulière. les valeurs d'une collection peuvent être dupliquées.]
« Membre de Superclass, Legacy and Collection Framework
Hashtable est une classe héritée introduite dans JDK1.0
, qui est une sous-classe de la classe Dictionary. From JDK1.2
Hashtable est repensé pour implémenter l' interface Map afin de devenir membre du framework de collecte. HashMap est membre de Java Collection Framework dès le début de son introduction dans JDK1.2
. HashMap est la sous-classe de la classe AbstractMap.
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
« Capacité initiale et facteur de charge
La capacité est le nombre de compartiments dans la table de hachage, et la capacité initiale est simplement la capacité au moment où la table de hachage est créée. Notez que la table de hachage est ouverte: dans le cas d'un " hash
collision
", un seul compartiment stocke plusieurs entrées, qui doivent être recherchées séquentiellement. Le facteur de charge est une mesure de la capacité maximale de la table de hachage à obtenir avant que sa capacité soit automatiquement augmentée.
HashMap construit une table de hachage vide avec la capacité initiale par défaut (16) et le facteur de charge par défaut (0,75). Là où Hashtable construit une table de hachage vide avec une capacité initiale par défaut (11) et un rapport facteur de charge / remplissage (0,75).
« Modification structurelle en cas de collision de hachage
HashMap
, Hashtable
en cas de collisions de hachage, ils stockent les entrées de la carte dans des listes chaînées. À partir de Java8,HashMap
si le compartiment de hachage dépasse un certain seuil, ce compartiment va basculer linked list of entries to a balanced tree
. qui améliorent les performances les plus défavorables de O (n) à O (log n). Lors de la conversion de la liste en arbre binaire, le code de hachage est utilisé comme variable de branchement. S'il y a deux codes de hachage différents dans le même compartiment, l'un est considéré comme plus grand et va à droite de l'arbre et l'autre à gauche. Mais lorsque les deux codes de hachage sont égaux, HashMap
suppose que les clés sont comparables et compare la clé pour déterminer la direction afin de maintenir un certain ordre. Il est recommandé de créer les clés deHashMap
comparables . Lors de l'ajout d'entrées si la taille du compartiment atteintTREEIFY_THRESHOLD = 8
convertir la liste des entrées liées en une arborescence équilibrée, en supprimant les entrées moins que TREEIFY_THRESHOLD
et au plus UNTREEIFY_THRESHOLD = 6
reconvertira l'arborescence équilibrée en liste des entrées liées. Java 8 SRC , stackpost
«Itération collection-vue, Fail-Fast et Fail-Safe
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iterator
est un échec de nature. c'est-à-dire qu'elle lève ConcurrentModificationException si une collection est modifiée lors de l'itération autre que sa propre méthode remove (). Où que Enumeration
soit de sécurité intrinsèque. Il ne lève aucune exception si une collection est modifiée pendant l'itération.
Selon Java API Docs, Iterator est toujours préféré à l'énumération.
REMARQUE: la fonctionnalité de l'interface d'énumération est dupliquée par l'interface Iterator. De plus, Iterator ajoute une opération de suppression facultative et a des noms de méthode plus courts. Les nouvelles implémentations devraient envisager d'utiliser Iterator de préférence à Enumeration.
En Java 5, l'interface ConcurrentMap a été introduite : ConcurrentHashMap
- une ConcurrentMap
implémentation hautement concurrente et performante soutenue par une table de hachage. Cette implémentation ne se bloque jamais lors des récupérations et permet au client de sélectionner le niveau de concurrence pour les mises à jour. Il se veut un remplacement de remplacement Hashtable
: en plus de l'implémentation ConcurrentMap
, il prend en charge toutes les méthodes "héritées" propres à Hashtable
.
La HashMapEntry
valeur de chaque s est volatile garantissant ainsi la cohérence du grain fin pour les modifications contestées et les lectures ultérieures; chaque lecture reflète la dernière mise à jour terminée
Les itérateurs et les énumérations sont à sécurité intégrée - reflétant l'état à un moment donné depuis la création de l'itérateur / énumération; cela permet des lectures et des modifications simultanées au prix d'une cohérence réduite. Ils ne lèvent pas ConcurrentModificationException. Cependant, les itérateurs sont conçus pour être utilisés par un seul thread à la fois.
Comme Hashtable
mais contrairement à HashMap
, cette classe ne permet pas d'utiliser null comme clé ou valeur.
public static void main(String[] args) {
//HashMap<String, Integer> hash = new HashMap<String, Integer>();
Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
//ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();
new Thread() {
@Override public void run() {
try {
for (int i = 10; i < 20; i++) {
sleepThread(1);
System.out.println("T1 :- Key"+i);
hash.put("Key"+i, i);
}
System.out.println( System.identityHashCode( hash ) );
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
new Thread() {
@Override public void run() {
try {
sleepThread(5);
// ConcurrentHashMap traverse using Iterator, Enumeration is Fail-Safe.
// Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
sleepThread(1);
System.out.println("T2 : "+ e.nextElement());
}
// HashMap traverse using Iterator, Enumeration is Fail-Fast.
/*
for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
sleepThread(1);
System.out.println("T2 : "+ it.next());
// ConcurrentModificationException at java.util.Hashtable$Enumerator.next
}
*/
/*
Set< Entry<String, Integer> > entrySet = hash.entrySet();
Iterator< Entry<String, Integer> > it = entrySet.iterator();
Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
while( entryEnumeration.hasMoreElements() ) {
sleepThread(1);
Entry<String, Integer> nextElement = entryEnumeration.nextElement();
System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
//java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
// at java.util.HashMap$EntryIterator.next
// at java.util.Collections$3.nextElement
}
*/
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
try {
unmodifiableMap.put("key4", "unmodifiableMap");
} catch (java.lang.UnsupportedOperationException e) {
System.err.println("UnsupportedOperationException : "+ e.getMessage() );
}
}
static void sleepThread( int sec ) {
try {
Thread.sleep( 1000 * sec );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
« Clés nulles et valeurs nulles
HashMap
autorise au maximum une clé nulle et un nombre quelconque de valeurs nulles. Où as Hashtable
n'autorise même pas une seule clé null et une valeur null, si la clé ou la valeur null est alors elle lève NullPointerException. Exemple
« Synchronisé, Thread Safe
Hashtable
est synchronisé en interne. Par conséquent, il est très sûr de l'utiliser Hashtable
dans des applications multithread. Où as HashMap
n'est pas synchronisé en interne. Par conséquent, il n'est pas sûr de l'utiliser HashMap
dans des applications multithreads sans synchronisation externe. Vous pouvez synchroniser en externe en HashMap
utilisant la Collections.synchronizedMap()
méthode.
« Performance
Comme il Hashtable
est synchronisé en interne, cela rend Hashtable
légèrement plus lent que le HashMap
.
@Voir