Différences entre HashMap et Hashtable?

3752

Quelles sont les différences entre a HashMapet a Hashtableen Java?

Quel est le plus efficace pour les applications non filetées?

dmanxiii
la source
17
HashTable est obsolète dans Java 1.7 et il est recommandé d'utiliser l'implémentation ConcurrentMap
MissFiona
@MissFiona Non, ce ConcurrentMapn'est pas nécessaire ici, car la question dit «applications non threadées», ce qui signifie que le threading / concurrence n'est pas un problème.
Basil Bourque

Réponses:

3775

Il existe plusieurs différences entre HashMapet Hashtableen Java:

  1. Hashtableest synchronisé , alors qu'il HashMapne l'est pas. Cela HashMapaméliore les applications non threadées, car les objets non synchronisés fonctionnent généralement mieux que les objets synchronisés.

  2. Hashtablen'autorise pas les nullclés ou les valeurs. HashMapautorise une nullclé et un nombre quelconque de nullvaleurs.

  3. L'une des sous-classes de HashMap est LinkedHashMap, donc dans le cas où vous souhaitez un ordre d'itération prévisible (qui est l'ordre d'insertion par défaut), vous pouvez facilement échanger le HashMappour un LinkedHashMap. Ce ne serait pas aussi facile si vous utilisiez Hashtable.

Étant donné que la synchronisation n'est pas un problème pour vous, je recommanderais HashMap. Si la synchronisation devient un problème, vous pouvez également regarder ConcurrentHashMap.

Josh Brown
la source
84
Si vous souhaitez rendre un thread HashMap sûr, utilisez Collections.synchronizedMap().
Rok Strniša
275
Je voudrais aussi commentaire que l'approche naïve de fil dans la sécurité Hashtable( « synchronisation chaque méthode doit prendre soin de tout problème de concurrence! ») Fait très bien pire pour les applications threadées. Il vaut mieux synchroniser en externe un HashMap(et réfléchir aux conséquences), ou utiliser une ConcurrentMapimplémentation (et exploiter son API étendue pour la concurrence). Conclusion: la seule raison d'utiliser Hashtableest lorsqu'une API héritée (à partir de 1996 environ) l'exige.
erickson
8
HashMap donne la flexibilité au programmeur d'écrire du code threadSafe lorsqu'ils l'utilisent réellement. Il arrivait rarement que j'avais besoin d'une collection thread-safe comme ConcurrentHashMap ou HashTable. Ce dont j'avais besoin, c'est d'un certain ensemble de fonctions ou de certaines instructions dans un bloc synchronisé pour être threadsafe.
Gaurava Agarwal
2
Hashtable est obsolète et nous utilisons HashMap pour un environnement non sûr pour les threads. Si vous avez besoin de la sécurité des threads, vous pouvez utiliser Collections.synchronizedMap () ou utiliser ConcurrentHashMap qui est plus efficace que la table de hachage.
Maneesh Kumar
1
C'est obsolète mais pas obsolète et je me demande pourquoi. Je suppose que supprimer cette classe (et Vector pour les mêmes raisons) casserait trop de code existant et annoter avec @Deprecated impliquerait une intention de supprimer le code, qui n'est apparemment pas là.
Jilles van Gurp
682

Notez que la plupart des réponses indiquent que Hashtable est synchronisé. En pratique, cela vous achète très peu. La synchronisation est sur les méthodes accesseur / mutateur qui arrêteront l'ajout ou la suppression simultanée de deux threads de la carte, mais dans le monde réel, vous aurez souvent besoin d'une synchronisation supplémentaire.

Un idiome très courant consiste à "vérifier puis mettre" - c'est-à-dire rechercher une entrée dans le Map, et l'ajouter si elle n'existe pas déjà. Ce n'est en aucun cas une opération atomique que vous utilisiez Hashtableou HashMap.

Une synchronisation équivalente HashMappeut être obtenue par:

Collections.synchronizedMap(myMap);

Mais pour implémenter correctement cette logique, vous avez besoin d' une synchronisation supplémentaire du formulaire:

synchronized(myMap) {
    if (!myMap.containsKey("tomato"))
        myMap.put("tomato", "red");
}

Même itérer sur Hashtableles entrées de a (ou celles HashMapobtenues par Collections.synchronizedMap) n'est pas sûr pour les threads, sauf si vous protégez également la Mapmodification par une synchronisation supplémentaire.

Les implémentations de l' ConcurrentMapinterface (par exemple ConcurrentHashMap) résolvent certains de ces problèmes en incluant une sémantique de vérification puis d'action sécurisée pour les threads telle que:

ConcurrentMap.putIfAbsent(key, value);
serg10
la source
53
Notez également que si un HashMap est modifié, les itérateurs pointant vers lui sont rendus invalides.
Chris K
3
Y a-t-il donc une différence entre synchronized (myMap) {...} et ConcurrentHashMap en termes de thread-safe?
telebog
3
Très vrai, j'ai essayé d'expliquer la même chose ici .. lovehasija.com/2012/08/16/…
Love Hasija
@Bhushan: Il lancera au mieux, ce n'est pas un comportement garanti: docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Matt Stephenson
Ayant été au milieu d'une équipe de développement JVM pendant un certain nombre d'années, je peux affirmer que la synchronisation interne de Hashtable est au moins utile pour pointer correctement le doigt sur le code du client lorsqu'il écrit du code concurrent douteux. Nous avons reçu plusieurs plaintes d'échecs dans HashMap (et donc "évidemment" un bogue JDK / JVM), lorsque la cause était une modification simultanée.
Hot Licks
363

Hashtableest considéré comme un code hérité. Il n'y a rien à Hashtablece sujet qui ne peut pas être fait en utilisant HashMapou en dérivant HashMap, donc pour le nouveau code, je ne vois aucune justification pour y revenir Hashtable.

aberrant80
la source
101
De Hashtable javadoc (non souligné dans l'original): "À partir de la plate-forme Java 2 v1.2, cette classe a été mise à niveau pour implémenter l'interface Map, ce qui en fait un membre du Java Collections Framework ." Cependant, vous avez raison, il s'agit d'un code hérité. Tous les avantages de la synchronisation peuvent être obtenus plus efficacement avec Collections.synchronizedMap (HashMap). (Similaire à Vector étant une version héritée de Collections.synchronizedList (ArrayList).)
Kip
15
@ aberrant80: malheureusement, vous n'avez pas le choix entre les deux et devez utiliser Hashtable lors de la programmation pour J2ME ...
pwes
6
cette réponse doit être supprimée. il contient des informations incorrectes et a beaucoup de votes positifs.
anon58192932
@ anon58192932 Est-il possible de modifier la question pour la corriger?
GC_
1
Nous devons attirer l'attention de l'affiche @ aberrant80 ou d'un administrateur en signalant. Marquer pourrait aider - va essayer maintenant.
anon58192932
189

Cette question est souvent posée en entrevue pour vérifier si le candidat comprend l'utilisation correcte des classes de collecte et est au courant des solutions alternatives disponibles.

  1. La HashMapclasse est à peu près équivalente à Hashtable, sauf qu'elle n'est pas synchronisée et autorise les valeurs NULL. ( HashMapautorise les valeurs nulles comme clé et valeur tandis que Hashtablene permet pas nulls).
  2. HashMap ne garantit pas que l'ordre de la carte restera constant dans le temps.
  3. HashMapn'est pas synchronisé alors qu'il Hashtableest synchronisé.
  4. L'itérateur dans l' HashMapest est à sécurité intégrée tandis que l'énumérateur pour l' Hashtableest ne l' est pas et jette ConcurrentModificationExceptionsi un autre thread modifie la carte structurellement en ajoutant ou en supprimant tout élément à l'exception de Iteratorla propre remove() méthode de. Mais ce n'est pas un comportement garanti et cela sera fait par JVM au mieux.

Remarque sur certains termes importants:

  1. Synchronisé signifie qu'un seul thread peut modifier une table de hachage à un moment donné. Fondamentalement, cela signifie que tout thread avant d'effectuer une mise à jour sur unHashtable devra acquérir un verrou sur l'objet tandis que d'autres attendront que le verrou soit libéré.
  2. La sécurité intégrée est pertinente dans le contexte des itérateurs. Si un itérateur a été créé sur un objet de collection et qu'un autre thread essaie de modifier l'objet de collection "structurellement", une exception de modification simultanée sera levée. Il est cependant possible pour d'autres threads d'appeler la setméthode car elle ne modifie pas la collection "structurellement". Cependant, si avant l'appel set, la collection a été modifiée structurellement, IllegalArgumentExceptionelle sera levée.
  3. La modification structurelle signifie la suppression ou l'insertion d'un élément qui pourrait effectivement changer la structure de la carte.

HashMap peut être synchronisé par

Map m = Collections.synchronizeMap(hashMap);

La carte fournit des vues de collection au lieu d'une prise en charge directe de l'itération via des objets d'énumération. Les vues de collection améliorent considérablement l'expressivité de l'interface, comme expliqué plus loin dans cette section. La carte vous permet d'itérer sur des clés, des valeurs ou des paires clé-valeur; Hashtablene fournit pas la troisième option. La carte fournit un moyen sûr de supprimer des entrées au milieu de l'itération; Hashtablenon. Enfin, Map corrige une lacune mineure dans l' Hashtableinterface. Hashtablea une méthode appelée contains, qui retourne true si le Hashtablecontient une valeur donnée. Étant donné son nom, vous vous attendriez à ce que cette méthode retourne true si elle Hashtablecontenait une clé donnée, car la clé est le mécanisme d'accès principal pour a Hashtable. L'interface Map élimine cette source de confusion en renommant la méthode containsValue. En outre, cela améliore la cohérence de l'interface - containsValueparallèles containsKey.

L'interface cartographique

sravan
la source
19
Cette réponse contient au moins 2 inexactitudes factuelles importantes. Il ne mérite certainement pas autant de votes positifs.
Stephen C
58
1) Les itérateurs de HashMap ne sont PAS à sécurité intégrée. Ils sont rapides. Il y a une énorme différence de sens entre ces deux termes. 2) Il n'y a aucune setopération sur a HashMap. 3) L' put(...)opération ne sera pas lancée IllegalArgumentExceptions'il y avait eu un changement précédent. 4) Le comportement de défaillance rapide HashMap se produit également si vous modifiez un mappage. 5) Le comportement fail-fast est garanti. (Ce qui n'est pas garanti, c'est le comportement d'un HashTablesi vous effectuez une modification simultanée. Le comportement réel est ... imprévisible.)
Stephen C
25
6) Hashtablene garantit pas non plus que l'ordre des éléments de la carte sera stable dans le temps. (Vous confondez peut-être Hashtableavec LinkedHashMap.)
Stephen C
4
Quelqu'un d'autre est-il vraiment inquiet que les étudiants aient de nos jours l'idée erronée que l'obtention de "versions synchronisées" des collections signifie que vous n'avez pas à synchroniser en externe les opérations composées? Mon exemple préféré de cet être thing.set(thing.get() + 1);qui, le plus souvent, surprend les débutants par surprise comme complètement non protégé, surtout si les méthodes get()et set()sont synchronisées. Beaucoup d'entre eux attendent de la magie.
Les itérateurs sur HashMap ne sont pas à sécurité intégrée
Abdul
130

HashMap: Une implémentation de l' Mapinterface qui utilise des codes de hachage pour indexer un tableau. Hashtable: Salut, 1998 appelé. Ils veulent récupérer leur API de collections.

Sérieusement, vous feriez mieux de rester loin de Hashtabletout à fait. Pour les applications monothread, vous n'avez pas besoin de la surcharge supplémentaire de synchronisation. Pour les applications hautement simultanées, la synchronisation paranoïaque peut entraîner la famine, des blocages ou des pauses inutiles de récupération de place. Comme l'a souligné Tim Howland, vous pouvez utiliser à la ConcurrentHashMapplace.

Apocalisp
la source
Cela a du sens. ConcurrentHashMaps vous donne la liberté de synchronisation et le débogage est beaucoup plus facile.
prap19
1
Est-ce spécifique à Java ou à toute l'implémentation de la carte de hachage.
125

Gardez à l'esprit que HashTablec'était une classe héritée avant l'introduction de Java Collections Framework (JCF) et qu'elle a été ultérieurement mise à niveau pour implémenter l' Mapinterface. Il en était de même Vectorpour Stack.

Par conséquent, restez toujours à l'écart d'eux dans le nouveau code car il y a toujours une meilleure alternative dans le JCF comme d'autres l'ont souligné.

Voici la feuille de triche de la collection Java que vous trouverez utile. Notez que le bloc gris contient la classe héritée HashTable, Vector et Stack.

entrez la description de l'image ici

pierrotlefou
la source
72

Il y a beaucoup de bonnes réponses déjà publiées. J'ajoute quelques nouveaux points et je le résume.

HashMapet les Hashtabledeux sont utilisés pour stocker des données sous forme de clé et de valeur . Les deux utilisent la technique de hachage pour stocker des clés uniques. Mais il existe de nombreuses différences entre les classes HashMap et Hashtable indiquées ci-dessous.

HashMap

  1. HashMapn'est pas synchronisé. Il n'est pas sûr pour les threads et ne peut pas être partagé entre plusieurs threads sans le bon code de synchronisation.
  2. HashMap autorise une clé nulle et plusieurs valeurs nulles.
  3. HashMap est une nouvelle classe introduite dans JDK 1.2.
  4. HashMap est rapide.
  5. Nous pouvons faire le HashMapcomme synchronisé en appelant ce code
    Map m = Collections.synchronizedMap(HashMap);
  6. HashMap est traversé par Iterator.
  7. Itérateur en HashMapest rapide.
  8. HashMap hérite de la classe AbstractMap.

Hashtable

  1. Hashtableest synchronisé. Il est thread-safe et peut être partagé avec de nombreux threads.
  2. Hashtable ne permet aucune clé ou valeur nulle.
  3. Hashtable est une classe héritée.
  4. Hashtable est lent.
  5. Hashtable est synchronisé en interne et ne peut pas être désynchronisé.
  6. Hashtable est traversé par Enumerator et Iterator.
  7. L'énumérateur dans Hashtablen'est pas infaillible.
  8. Hashtable hérite de la classe Dictionary.

Pour en savoir plus Quelle est la différence entre HashMap et Hashtable en Java?

entrez la description de l'image ici

roottraveller
la source
Assez couvert dans cette réponse (en double de) - stackoverflow.com/a/39785829/432903 .
Prayagupd
Pourquoi dites-vous ~ " Hashtable est une classe héritée "? Où est la documentation à l'appui de cela.
IgorGanapolsky
2
@IgorGanapolsky vous pouvez lire ceci - stackoverflow.com/questions/21086307/…
roottraveller
La maintenance de HashMap est coûteuse que TreeMap. Parce que HashMap crée des compartiments supplémentaires inutiles.
Abdul
64

En plus de ce que dit izb, HashMapautorise les valeurs nulles, alors que le Hashtablene le fait pas.

Notez également que Hashtableétend la Dictionaryclasse, qui, comme l' état Javadocs , est obsolète et a été remplacée par l' Mapinterface.

mat b
la source
3
mais cela ne rend pas le HashTable obsolète n'est-ce pas?
Pacerier
@Pacerier HashTable est obsolète depuis Java 1.7.
Majid Ali Khan
62

Jetez un œil à ce tableau. Il fournit des comparaisons entre différentes structures de données avec HashMapet Hashtable. La comparaison est précise, claire et facile à comprendre.

Matrice de collection Java

Sujan
la source
49

Hashtableest similaire à HashMapet possède une interface similaire. Il est recommandé de l'utiliser HashMap, sauf si vous avez besoin de la prise en charge des applications héritées ou si vous avez besoin d'une synchronisation, car les Hashtablesméthodes sont synchronisées. Donc, dans votre cas, comme vous n'êtes pas multi-threading, HashMapsvous êtes le meilleur choix.

Miles D
la source
36

Une autre différence clé entre la table de hachage et la table de hachage est que l'itérateur dans la table de hachage est rapide, tandis que l'énumérateur de la table de hachage ne l'est pas et lève ConcurrentModificationException si un autre thread modifie structurellement la carte en ajoutant ou en supprimant tout élément à l'exception de la méthode remove () d'itérateur. Mais ce n'est pas un comportement garanti et cela sera fait par JVM au mieux. "

Ma source: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html

Neerja
la source
36

Outre tous les autres aspects importants déjà mentionnés ici, l'API Collections (par exemple, l'interface Map) est constamment modifiée pour se conformer aux "dernières et meilleures" ajouts aux spécifications Java.

Par exemple, comparez l'itération de la carte Java 5:

for (Elem elem : map.keys()) {
  elem.doSth();
}

par rapport à l'ancienne approche Hashtable:

for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
  Elem elem = (Elem) en.nextElement();
  elem.doSth();
}

Dans Java 1.8, on nous promet également de pouvoir construire et accéder à des HashMaps comme dans les bons vieux langages de script:

Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];

Mise à jour: Non, ils n'atterriront pas en 1.8 ... :(

Les améliorations de la collection de Project Coin seront-elles dans JDK8?

pwes
la source
34

Hashtableest synchronisé, alors qu'il HashMapne l'est pas. Cela rend Hashtableplus lent que Hashmap.

Pour les applications non filetées, utilisez-les HashMapcar elles sont par ailleurs les mêmes en termes de fonctionnalités.

izb
la source
30
  • HashTable est synchronisé, si vous l'utilisez dans un seul thread, vous pouvez utiliser HashMap , qui est une version non synchronisée. Les objets non synchronisés sont souvent un peu plus performants. Soit dit en passant, si plusieurs threads accèdent simultanément à un HashMap et qu'au moins l'un des threads modifie la carte structurellement, il doit être synchronisé en externe. Vous pouvez envelopper une carte non synchronisée dans une carte synchronisée en utilisant:

    Map m = Collections.synchronizedMap(new HashMap(...));
  • HashTable ne peut contenir que des objets non nuls sous forme de clé ou de valeur. HashMap peut contenir une clé null et des valeurs null.

  • Les itérateurs retournés par Map sont résistants aux défaillances, si la map est structurellement modifiée à tout moment après la création de l'itérateur, de quelque manière que ce soit, sauf par la méthode de suppression de l'itérateur, l'itérateur lance un ConcurrentModificationException. Ainsi, face à une modification simultanée, l'itérateur échoue rapidement et proprement, plutôt que de risquer un comportement arbitraire et non déterministe à un moment indéterminé dans le futur. Tandis que les énumérations renvoyées par les méthodes de clés et d'éléments de Hashtable ne sont pas rapides.

  • HashTable et HashMap sont membres du Java Collections Framework (depuis la plate-forme Java 2 v1.2, HashTable a été modernisé pour implémenter l'interface Map).

  • HashTable est considéré comme du code hérité, la documentation conseille d'utiliser ConcurrentHashMap à la place de Hashtable si une implémentation hautement concurrente thread-safe est souhaitée.

  • HashMap ne garantit pas l'ordre dans lequel les éléments sont retournés. Pour HashTable, je suppose que c'est la même chose mais je ne suis pas tout à fait sûr, je ne trouve pas de ressource qui l'indique clairement.

alain.janinm
la source
30

HashMapet Hashtableprésentent également des différences algorithmiques importantes. Personne ne l'a mentionné auparavant, c'est pourquoi je le soulève. HashMapva construire une table de hachage avec une puissance de deux tailles, l'augmenter dynamiquement de sorte que vous ayez au plus environ huit éléments (collisions) dans n'importe quel compartiment et agitera très bien les éléments pour les types d'éléments généraux. Cependant, l' Hashtableimplémentation fournit un contrôle meilleur et plus fin du hachage si vous savez ce que vous faites, à savoir que vous pouvez fixer la taille de la table en utilisant, par exemple, le nombre premier le plus proche de la taille de votre domaine de valeurs et cela se traduira par de meilleures performances que HashMap, c'est-à-dire moins de collisions pour certains cas.

Indépendamment des différences évidentes discutées en détail dans cette question, je vois la Hashtable comme une voiture à "conduite manuelle" où vous avez un meilleur contrôle sur le hachage et la HashMap comme la contrepartie à "conduite automatique" qui fonctionnera généralement bien.

SkyWalker
la source
27

Sur la base des informations ici , je recommanderais d'utiliser HashMap. Je pense que le plus grand avantage est que Java vous empêchera de le modifier pendant que vous itérez dessus, à moins que vous ne le fassiez via l'itérateur.

pkaeding
la source
5
Il ne l'empêche pas, il le détecte simplement et génère une erreur.
Bart van Heukelom
1
Je suis presque sûr qu'il lèvera une ConncurrentModificationException avant que la collection sous-jacente ne soit modifiée, bien que je puisse me tromper.
pkaeding
Il tentera de détecter les modifications simultanées et de lever une exception. Mais si vous faites quoi que ce soit avec des threads, il ne peut faire aucune promesse. Absolument tout peut arriver, y compris la casse .
cHao
24

Un Collection- parfois appelé conteneur - est simplement un objet qui regroupe plusieurs éléments en une seule unité. Collections 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.2et 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 Entryobjet. La collection d'entrées est référencée par l'objet de HashMapet 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.2Hashtable 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 " hashcollision", 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).

Carte de hachage et table de hachage

« Modification structurelle en cas de collision de hachage

HashMap, Hashtableen 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, HashMapsuppose 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 = 8convertir 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 = 6reconvertira 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      |
    +--------------------+-----------+-------------+

Iteratorest 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 Enumerationsoit 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 ConcurrentMapimplé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 HashMapEntryvaleur 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 Hashtablemais 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

HashMapautorise au maximum une clé nulle et un nombre quelconque de valeurs nulles. Où as Hashtablen'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

Hashtableest synchronisé en interne. Par conséquent, il est très sûr de l'utiliser Hashtabledans des applications multithread. Où as HashMapn'est pas synchronisé en interne. Par conséquent, il n'est pas sûr de l'utiliser HashMapdans des applications multithreads sans synchronisation externe. Vous pouvez synchroniser en externe en HashMaputilisant la Collections.synchronizedMap()méthode.

« Performance

Comme il Hashtableest synchronisé en interne, cela rend Hashtablelégèrement plus lent que le HashMap.


@Voir

Yash
la source
18

Pour les applications filetées, vous pouvez souvent vous en sortir avec ConcurrentHashMap - cela dépend de vos exigences de performances.

Tim Howland
la source
17

1. Hashmapet à la HashTablefois stocker la clé et la valeur.

2. Hashmappeut stocker une clé sous null. Hashtablene peut pas stocker null.

3. HashMapn'est pas synchronisé mais Hashtableest synchronisé.

4. HashMappeut être synchronisé avecCollection.SyncronizedMap(map)

Map hashmap = new HashMap();

Map map = Collections.SyncronizedMap(hashmap);
Rahul Tripathi
la source
16

Outre les différences déjà mentionnées, il convient de noter que depuis Java 8, HashMapremplace dynamiquement les nœuds (liste liée) utilisés dans chaque compartiment par TreeNodes (arbre rouge-noir), de sorte que même en cas de collisions de hachage élevées, le pire des cas lorsque la recherche est

O (log (n)) pour HashMap Vs O (n) in Hashtable.

* L'amélioration mentionnée ci - dessus n'a pas été appliquée Hashtableencore, mais seulement HashMap, LinkedHashMapet ConcurrentHashMap.

Pour info, actuellement,

  • TREEIFY_THRESHOLD = 8 : si un compartiment contient plus de 8 nœuds, la liste chaînée est transformée en une arborescence équilibrée.
  • UNTREEIFY_THRESHOLD = 6 : lorsqu'un compartiment devient trop petit (en raison de la suppression ou du redimensionnement), l'arborescence est reconvertie en liste liée.
Kostas Chalkias
la source
14

Il existe 5 différenciations de base avec HashTable et HashMaps.

  1. Les cartes vous permettent d'itérer et de récupérer des clés, des valeurs et les deux paires clé-valeur également, où HashTable n'a pas toutes ces capacités.
  2. Dans Hashtable, il existe une fonction contains (), ce qui est très déroutant à utiliser. Parce que la signification de contient est légèrement différente. Que cela signifie contient la clé ou contient la valeur? difficile à comprendre. Même chose dans Maps, nous avons les fonctions ContainsKey () et ContainsValue (), qui sont très faciles à comprendre.
  3. Dans hashmap, vous pouvez supprimer l'élément pendant l'itération, en toute sécurité. où comme ce n'est pas possible dans les tables de hachage.
  4. Les HashTables sont synchronisés par défaut, il peut donc être utilisé avec plusieurs threads facilement. Là où les HashMaps ne sont pas synchronisés par défaut, ils peuvent donc être utilisés avec un seul thread. Mais vous pouvez toujours convertir HashMap en synchronisé en utilisant la fonction synchronizedMap (Map m) de la classe util Collections.
  5. HashTable n'autorisera pas les clés nulles ou les valeurs nulles. Alors que HashMap autorise une clé nulle et plusieurs valeurs nulles.
user1923551
la source
13

Ma petite contribution:

  1. La première et la plus importante différence entre Hashtableet HashMapest que, HashMapn'est pas thread-safe alors qu'il Hashtables'agit d'une collection thread-safe.

  2. La deuxième différence importante entre Hashtableet HashMapest la performance, car HashMapnon synchronisé, il fonctionne mieux que Hashtable.

  3. La troisième différence sur Hashtablevs HashMapest que Hashtablec'est une classe obsolète et que vous devriez utiliser ConcurrentHashMapà la place de HashtableJava.

Shreyos Adikari
la source
11

HashMap: C'est une classe disponible dans le package java.util et elle est utilisée pour stocker l'élément au format clé et valeur.

Hashtable: C'est une classe héritée qui est reconnue dans le cadre de la collection.

Ankit
la source
Si tel est le cas, cela ne devrait pas être une réponse dans les commentaires.
manikant gautam
10

HashTable est une classe héritée du jdk qui ne devrait plus être utilisée. Remplacez les utilisations de celui-ci par ConcurrentHashMap . Si vous n'avez pas besoin de la sécurité des threads, utilisez HashMap qui n'est pas threadsafe mais plus rapide et utilise moins de mémoire.

jontejj
la source
Parce que je pensais que les autres réponses, à l'époque, n'avaient pas rejeté HashTable mais expliqué que c'était threadsafe. La vérité est que dès que vous voyez HashTable dans le code, vous devez le remplacer par ConcurrentHashMap sans sauter un battement. Et si la sécurité des threads n'est pas un problème, HashMap peut être utilisé pour améliorer un peu les performances.
jontejj
10
  1. Hashtable est synchronisé alors que HashMap ne l'est pas.
  2. Une autre différence est que l'itérateur dans le HashMapest à sécurité intégrée tandis que l'énumérateur pour le Hashtablen'est pas. Si vous modifiez la carte pendant l'itération, vous le saurez.
  3. HashMapautorise des valeurs nulles, tandis Hashtableque non.
raja
la source
3
L'itérateur HashMap est à sécurité intégrée et non à sécurité intégrée. C'est pourquoi nous avons ConcurrentHashMap qui permet la modification pendant l'itération. Consultez cet article journaldev.com/122/…
Pankaj
9

HashMap et HashTable

  • Quelques points importants sur HashMap et HashTable. veuillez lire les détails ci-dessous.

1) Hashtable et Hashmap implémentent l'interface java.util.Map 2) Hashmap et Hashtable est la collection basée sur le hachage. et travailler sur le hachage. ce sont donc des similitudes entre HashMap et HashTable.

  • Quelle est la différence entre HashMap et HashTable?

1) La première différence est que HashMap n'est pas sûr pour les threads tandis que HashTable est pour ThreadSafe
2) HashMap est plus performant car il n'est pas sûr pour les threads. tandis que les performances de Hashtable ne sont pas meilleures car elles sont sûres pour les threads. donc plusieurs threads ne peuvent pas accéder à Hashtable en même temps.

JegsVala
la source
2
Voté parce que cette réponse n'est pas correcte à certains égards. Hashtable n'implémente pas l'interface Map, mais étend uniquement la classe Dictionary, qui est obsolète.
Yannis Sermetziadis
8

Hashtable:

Hashtable est une structure de données qui conserve les valeurs de la paire clé-valeur. Il n'autorise pas null pour les clés et les valeurs. Vous obtiendrez un NullPointerExceptionsi vous ajoutez une valeur nulle. Il est synchronisé. Cela vient donc avec son coût. Un seul thread peut accéder à HashTable à un moment donné.

Exemple :

import java.util.Map;
import java.util.Hashtable;

public class TestClass {

    public static void main(String args[ ]) {
    Map<Integer,String> states= new Hashtable<Integer,String>();
    states.put(1, "INDIA");
    states.put(2, "USA");

    states.put(3, null);    //will throw NullPointerEcxeption at runtime

    System.out.println(states.get(1));
    System.out.println(states.get(2));
//  System.out.println(states.get(3));

    }
}

HashMap:

HashMap est comme Hashtable mais il accepte également une paire de valeurs clés. Il autorise null pour les clés et les valeurs. Ses performances sont meilleures que HashTable, car elles le sont unsynchronized.

Exemple:

import java.util.HashMap;
import java.util.Map;

public class TestClass {

    public static void main(String args[ ]) {
    Map<Integer,String> states = new HashMap<Integer,String>();
    states.put(1, "INDIA");
    states.put(2, "USA");

    states.put(3, null);    // Okay
    states.put(null,"UK");

    System.out.println(states.get(1));
    System.out.println(states.get(2));
    System.out.println(states.get(3));

    }
}
IntelliJ Amiya
la source
5

HashMapest émulé et donc utilisable en GWT client codealors qu'il Hashtablene l'est pas.

pong
la source
Est-ce une description complète des différences entre les deux API?
IgorGanapolsky
Oui (sic!). C'est tout ce que les développeurs de GWT doivent savoir à ce sujet.
pong
5

Sujet ancien et classique, je veux juste ajouter ce blog utile qui explique ceci:

http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/

Blog de Manish Chhabra

Les 5 principales différences entre HashMap et Hashtable

HashMap et Hashtable implémentent tous deux l'interface java.util.Map mais il y a quelques différences que les développeurs Java doivent comprendre pour écrire du code plus efficace. Depuis la plate-forme Java 2 v1.2, la classe Hashtable a été mise à niveau pour implémenter l'interface Map, ce qui en fait un membre de Java Collections Framework.

  1. L'une des principales différences entre HashMap et Hashtable est que HashMap n'est pas synchronisé tandis que Hashtable est synchronisé, ce qui signifie que Hashtable est thread-safe et peut être partagé entre plusieurs threads mais HashMap ne peut pas être partagé entre plusieurs threads sans synchronisation appropriée. Java 5 a introduit ConcurrentHashMap qui est une alternative à Hashtable et offre une meilleure évolutivité que Hashtable en Java.Synchronized signifie qu'un seul thread peut modifier une table de hachage à un moment donné. Fondamentalement, cela signifie que tout thread avant d'effectuer une mise à jour sur une table de hachage devra acquérir un verrou sur l'objet tandis que d'autres attendront que le verrou soit libéré.

  2. La classe HashMap est à peu près équivalente à Hashtable, sauf qu'elle autorise les null. (HashMap autorise les valeurs nulles comme clé et valeur alors que Hashtable n'autorise pas les valeurs nulles).

  3. La troisième différence significative entre HashMap et Hashtable est que l'itérateur dans le HashMap est un itérateur à échec rapide tandis que l'énumérateur pour le Hashtable ne l'est pas et lève ConcurrentModificationException si un autre thread modifie la carte structurellement en ajoutant ou en supprimant tout élément sauf le propre retrait d'itérateur ( ) méthode. Mais ce n'est pas un comportement garanti et cela sera fait par JVM au mieux. C'est également une différence importante entre l'énumération et l'itérateur en Java.

  4. Une différence plus notable entre Hashtable et HashMap est qu'en raison de la sécurité des threads et de la synchronisation, Hashtable est beaucoup plus lent que HashMap s'il est utilisé dans un environnement à thread unique. Donc, si vous n'avez pas besoin de synchronisation et que HashMap n'est utilisé que par un seul thread, il exécute Hashtable en Java.

  5. HashMap ne garantit pas que l'ordre de la carte restera constant dans le temps.

Notez que HashMap peut être synchronisé par

Map m = Collections.synchronizedMap(hashMap);

En résumé, il existe des différences significatives entre Hashtable et HashMap en Java, par exemple la sécurité des threads et la vitesse, et sur cette base, n'utilisez Hashtable que si vous avez absolument besoin de la sécurité des threads, si vous exécutez Java 5, envisagez d'utiliser ConcurrentHashMap en Java.

Nuit0
la source
ConcurrentHashMap n'est pas synchronisé en lecture, contrairement à Hashtable. Donc, si vous avez un grand nombre d'opérations de lecture se produisant simultanément avec les écritures, une table de hachage vous serait plus utile si vous vous souciez de l'intégrité des données.
IgorGanapolsky
5

HashMap et Hashtable sont tous deux utilisés pour stocker des données sous forme de clé et de valeur. Les deux utilisent la technique de hachage pour stocker des clés uniques. ut il existe de nombreuses différences entre les classes HashMap et Hashtable qui sont données ci-dessous.

entrez la description de l'image ici

Déc
la source
Beau résumé visuel!
Nadjib Mami