Differenze tra HashMap e Hashtable?


3751

Quali sono le differenze tra a HashMape a Hashtablein Java?

Qual è più efficiente per le applicazioni senza thread?


17
HashTable è obsoleto in Java 1.7 ed è consigliabile utilizzare l'implementazione ConcurrentMap
MissFiona

@MissFiona No, nonConcurrentMap è necessario qui, poiché la domanda dice che "applicazioni non threaded" significa che il threading / concorrenza non è un problema.
Basil Bourque,

Risposte:


3775

Esistono diverse differenze tra HashMape Hashtablein Java:

  1. Hashtableè sincronizzato , mentre HashMapnon lo è. Ciò HashMapmigliora le applicazioni senza thread, poiché gli oggetti non sincronizzati in genere funzionano meglio di quelli sincronizzati.

  2. Hashtablenon consente nullchiavi o valori. HashMapconsente una nullchiave e qualsiasi numero di nullvalori.

  3. Una delle sottoclassi di HashMap è LinkedHashMap, quindi nel caso in cui si desideri un ordine di iterazione prevedibile (che è l'ordine di inserimento per impostazione predefinita), è possibile scambiare facilmente HashMapun con LinkedHashMap. Non sarebbe così facile se lo stessi usando Hashtable.

Dal momento che la sincronizzazione non è un problema per te, ti consiglio HashMap. Se la sincronizzazione diventa un problema, puoi anche esaminare ConcurrentHashMap.


84
Se vuoi rendere un thread HashMap sicuro, usa Collections.synchronizedMap().
Rok Strniša,

275
Vorrei anche commentare che l'approccio ingenuo alla sicurezza dei thread in Hashtable("la sincronizzazione di ogni metodo dovrebbe occuparsi di eventuali problemi di concorrenza!") Rende molto peggio per le applicazioni thread. Stai meglio sincronizzando esternamente un HashMap(e pensando alle conseguenze), o usando ConcurrentMapun'implementazione (e sfruttando la sua API estesa per la concorrenza). In conclusione: l'unico motivo da utilizzare Hashtableè quando un'API legacy (dal 1996 circa) lo richiede.
Erickson,

8
HashMap offre flessibilità al programmatore di scrivere codice threadSafe quando lo usano effettivamente. Accade raramente di aver bisogno di una raccolta thread-safe come ConcurrentHashMap o HashTable. Ciò di cui avevo bisogno è che un certo set di funzioni o determinate istruzioni in un blocco sincronizzato siano thread-safe.
Gaurava Agarwal,

2
Hashtable è obsoleto e stiamo usando HashMap per un ambiente non thread-safe. Se hai bisogno della sicurezza dei thread, puoi utilizzare Collections.synchronizedMap () o ConcurrentHashMap, che è più efficiente della tabella hash.
Maneesh Kumar,

1
È obsoleto ma non deprecato e mi chiedo perché sia ​​così. Suppongo che rimuovere questa classe (e Vector per gli stessi motivi) rompa troppo il codice esistente e annotare con @Deprecated implicherebbe l'intenzione di rimuovere il codice, che apparentemente non c'è.
Jilles van Gurp,

682

Nota che molte delle risposte affermano che Hashtable è sincronizzato. In pratica questo ti compra molto poco. La sincronizzazione è sui metodi di accesso / mutatore impedirà a due thread di aggiungere o rimuovere contemporaneamente dalla mappa, ma nel mondo reale avrai spesso bisogno di una sincronizzazione aggiuntiva.

Un linguaggio molto comune è "controlla e poi metti", ovvero cerca una voce nel Mape aggiungila se non esiste già. Non si tratta in alcun modo di un'operazione atomica sia che si usi Hashtableo HashMap.

Un equivalente sincronizzato HashMappuò essere ottenuto da:

Collections.synchronizedMap(myMap);

Ma per implementare correttamente questa logica è necessaria un'ulteriore sincronizzazione del modulo:

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

Anche l'iterazione sulle Hashtablevoci di a (o un HashMapottenuto da Collections.synchronizedMap) non è thread-safe a meno che non si protegga anche la Mapmodifica tramite una sincronizzazione aggiuntiva.

Le implementazioni ConcurrentMapdell'interfaccia (ad esempio ConcurrentHashMap) risolvono alcune di queste includendo la semantica check-then-act thread-safe come:

ConcurrentMap.putIfAbsent(key, value);

53
Inoltre, se una HashMap viene modificata, gli iteratori che la puntano vengono resi non validi.
Chris K,

3
Quindi c'è qualche differenza tra sincronizzato (myMap) {...} e ConcurrentHashMap in termini di thread-safe?
Telemog

3
Molto vero, ho cercato di spiegare lo stesso qui .. lovehasija.com/2012/08/16/…
Love Hasija

@Bhushan: genererà il massimo sforzo, questo non è un comportamento garantito: docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Matt Stephenson

Essendo stato nel mezzo di una squadra di sviluppo di JVM per diversi anni, posso affermare che la sincronizzazione interna di Hashtable è almeno utile per puntare correttamente il dito sul codice del cliente quando scrive un codice concorrente poco chiaro. Abbiamo ricevuto diverse denunce di guasti all'interno di HashMap (e quindi "ovviamente" un bug JDK / JVM), quando la causa era la modifica simultanea.
Hot Licks

363

Hashtableè considerato codice legacy. Non c'è nulla Hashtableche non possa essere fatto usando HashMapo derivando HashMap, quindi per il nuovo codice, non vedo alcuna giustificazione per tornare a Hashtable.


101
Da Hashtable javadoc (enfasi aggiunta): "A partire dalla piattaforma Java 2 v1.2, questa classe è stata adattata per implementare l'interfaccia Map, rendendola membro del Java Collections Framework ." Tuttavia, hai ragione nel dire che è un codice legacy. Tutti i vantaggi della sincronizzazione possono essere ottenuti in modo più efficiente con Collections.synchronizedMap (HashMap). (Simile a Vector essendo una versione legacy di Collections.synchronizedList (ArrayList).)
Kip

15
@ aberrant80: sfortunatamente non hai scelta tra i due e devi usare Hashtable durante la programmazione per J2ME ...
pwes

6
questa risposta dovrebbe essere cancellata. contiene informazioni errate e molti voti positivi.
anon58192932

@ anon58192932 È possibile modificare la domanda per risolverlo?
GC_

1
Dobbiamo attirare l'attenzione del poster @ aberrant80 o di un amministratore segnalando. Contrassegnare potrebbe aiutare - ci proverò ora.
anon58192932

189

Questa domanda viene spesso posta in un'intervista per verificare se il candidato comprende il corretto utilizzo delle classi di raccolta ed è a conoscenza di soluzioni alternative disponibili.

  1. La HashMapclasse è approssimativamente equivalente a Hashtable, tranne per il fatto che non è sincronizzata e consente valori null. ( HashMapconsente valori null come chiave e valore mentre Hashtablenon consente nulls).
  2. HashMap non garantisce che l'ordine della mappa rimarrà costante nel tempo.
  3. HashMapnon è sincronizzato mentre Hashtableè sincronizzato.
  4. Iteratore in HashMapè a prova di errore mentre l'enumeratore per non lo Hashtableè e genera ConcurrentModificationExceptionse un altro thread modifica strutturalmente la mappa aggiungendo o rimuovendo qualsiasi elemento tranne Iteratoril remove() metodo proprio . Ma questo non è un comportamento garantito e sarà fatto da JVM con il massimo sforzo.

Nota su alcuni termini importanti:

  1. Sincronizzato significa che solo un thread può modificare una tabella hash in un determinato momento. Fondamentalmente, significa che qualsiasi thread prima di eseguire un aggiornamento su Hashtabledovrà acquisire un blocco sull'oggetto mentre altri aspetteranno il rilascio del blocco.
  2. Fail-safe è rilevante nel contesto degli iteratori. Se un iteratore è stato creato su un oggetto di raccolta e qualche altro thread tenta di modificare l'oggetto di raccolta "strutturalmente", verrà generata un'eccezione di modifica concorrente. È possibile che altri thread invochino il setmetodo poiché non modifica la raccolta "strutturalmente". Tuttavia, se prima di chiamare set, la raccolta è stata modificata strutturalmente, IllegalArgumentExceptionverrà lanciata.
  3. Modifica strutturalmente significa l'eliminazione o l'inserimento di elementi che potrebbero effettivamente modificare la struttura della mappa.

HashMap può essere sincronizzato da

Map m = Collections.synchronizeMap(hashMap);

Mappa fornisce viste Collection invece del supporto diretto per l'iterazione tramite oggetti Enumeration. Le viste della raccolta migliorano notevolmente l'espressività dell'interfaccia, come discusso più avanti in questa sezione. Mappa consente di scorrere su chiavi, valori o coppie chiave-valore; Hashtablenon fornisce la terza opzione. Mappa fornisce un modo sicuro per rimuovere le voci nel mezzo dell'iterazione; Hashtableno. Infine, Map risolve un piccolo difetto Hashtablenell'interfaccia. Hashtableha un metodo chiamato contiene, che restituisce vero se Hashtablecontiene un determinato valore. Dato il suo nome, ti aspetteresti che questo metodo restituisca true se Hashtableconteneva una determinata chiave, poiché la chiave è il meccanismo di accesso principale per a Hashtable. L'interfaccia Mappa elimina questa fonte di confusione rinominando il metodo containsValue. Inoltre, ciò migliora la coerenza dell'interfaccia: containsValueparallelismi containsKey.

L'interfaccia della mappa


19
Questa risposta contiene almeno 2 imprecisioni di fatto significative. Certamente NON merita così tanti voti.
Stephen C,

58
1) Gli iteratori di HashMap NON sono a prova di errore. Sono fail-fast. C'è un'enorme differenza di significato tra questi due termini. 2) Non ci sono setoperazioni su a HashMap. 3) L' put(...)operazione non verrà avviata IllegalArgumentExceptionse è stata apportata una modifica precedente. 4) Il comportamento fail-fast di HashMap si verifica anche se si modifica una mappatura. 5) Il comportamento fail-fast è garantito. (Ciò che non è garantito è il comportamento di a HashTablese si apportano modifiche simultanee. Il comportamento effettivo è ... imprevedibile.)
Stephen C

25
6) Hashtablenon garantisce che l'ordine degli elementi della mappa sia stabile nel tempo. (Stai forse confondendo Hashtablecon LinkedHashMap.)
Stephen C

4
Qualcun altro si è davvero preoccupato che gli studenti oggigiorno stiano ottenendo l'idea errata che ottenere "versioni sincronizzate" delle raccolte in qualche modo significhi che non è necessario sincronizzare esternamente le operazioni composte? Il mio esempio preferito di questo essere thing.set(thing.get() + 1);, che il più delle volte non coglie di sorpresa i neofiti come completamente non protetti, soprattutto se l' get()e set()sono sincronizzati metodi. Molti di loro si aspettano la magia.

Iteratori su HashMap non è a prova di errore
Abdul,

130

HashMap: Un'implementazione Mapdell'interfaccia che utilizza i codici hash per indicizzare un array. Hashtable: Ciao, 1998 ha chiamato. Vogliono indietro le loro API delle collezioni.

Scherzi a parte, è meglio stare lontani del Hashtabletutto. Per le app a thread singolo, non è necessario l'overhead aggiuntivo della sincronizzazione. Per le app altamente concorrenti, la sincronizzazione paranoica potrebbe causare fame, deadlock o pause inutili di garbage collection. Come ha sottolineato Tim Howland, potresti usare ConcurrentHashMapinvece.


Questo in realtà ha senso. ConcurrentHashMaps ti dà la libertà di sincronizzazione e il debug è molto più semplice.
prap19

1
È specifico per Java o per l'implementazione di tutte le mappe hash.

125

Tenere presente che HashTableera una classe legacy prima dell'introduzione di Java Collections Framework (JCF) e successivamente adattata per implementare l' Mapinterfaccia. Così è stato Vectore Stack.

Pertanto, state sempre alla larga da loro nel nuovo codice poiché vi sono sempre alternative migliori nel JCF, come altri hanno sottolineato.

Ecco il cheat sheet della collezione Java che troverai utile. Notare che il blocco grigio contiene la classe legacy HashTable, Vector e Stack.

inserisci qui la descrizione dell'immagine


72

Ci sono già molte buone risposte già pubblicate. Sto aggiungendo alcuni nuovi punti e lo riassumo.

HashMaped Hashtableentrambi vengono utilizzati per archiviare i dati in forma chiave e valore . Entrambi utilizzano la tecnica di hashing per memorizzare chiavi univoche. Ma ci sono molte differenze tra le classi HashMap e Hashtable riportate di seguito.

HashMap

  1. HashMapnon è sincronizzato. Non è sicuro per i thread e non può essere condiviso tra molti thread senza un codice di sincronizzazione adeguato.
  2. HashMap consente una chiave null e più valori null.
  3. HashMap è una nuova classe introdotta in JDK 1.2.
  4. HashMap è veloce.
  5. Possiamo renderlo HashMapsincronizzato chiamando questo codice
    Map m = Collections.synchronizedMap(HashMap);
  6. HashMap è attraversato da Iterator.
  7. Iterator in HashMapè fail-fast.
  8. HashMap eredita la classe AbstractMap.

tabella hash

  1. Hashtableè sincronizzato. È thread-safe e può essere condiviso con molti thread.
  2. Hashtable non consente alcuna chiave o valore null.
  3. Hashtable è una classe legacy.
  4. Hashtable è lento.
  5. Hashtable è sincronizzato internamente e non può essere non sincronizzato.
  6. Hashtable è attraversato da Enumeratore e Iteratore.
  7. L'enumeratore in Hashtablenon è fail-fast.
  8. Hashtable eredita la classe del dizionario.

Ulteriori letture Qual è la differenza tra HashMap e Hashtable in Java?

inserisci qui la descrizione dell'immagine


Praticamente coperto in questa risposta (dupicate di) - stackoverflow.com/a/39785829/432903 .
prayagupd,

Perché dici ~ " Hashtable è una classe legacy "? Dov'è la documentazione di supporto per questo.
IgorGanapolsky

2
@IgorGanapolsky si può leggere questo - stackoverflow.com/questions/21086307/...
roottraveller

Il mantenimento di HashMap è costoso rispetto a TreeMap. Perché HashMap crea bucket aggiuntivi non necessari.
Abdul,

64

Oltre a ciò che ha detto izb, HashMapconsente valori nulli, mentre Hashtablenon lo è.

Si noti inoltre che Hashtableestende la Dictionaryclasse, che come lo stato Javadocs , è obsoleta ed è stata sostituita Mapdall'interfaccia.


3
ma ciò non rende obsoleta la HashTable?
Pacerier

@Pacerier HashTable è obsoleto da Java 1.7.
Majid Ali Khan,

62

Dai un'occhiata a questo grafico. Fornisce confronti tra diverse strutture di dati insieme a HashMape Hashtable. Il confronto è preciso, chiaro e di facile comprensione.

Matrix Collection Java


49

Hashtableè simile al HashMape ha un'interfaccia simile. Si consiglia di utilizzare HashMap, a meno che non sia necessario il supporto per le applicazioni legacy o la sincronizzazione, poiché i Hashtablesmetodi sono sincronizzati. Quindi, nel tuo caso, poiché non sei multithreading, HashMapssono la soluzione migliore.


36

Un'altra differenza chiave tra hashtable e hashmap è che Iterator in HashMap è fail-fast mentre l'enumeratore per Hashtable non lo è e lancia ConcurrentModificationException se qualsiasi altro thread modifica strutturalmente la mappa aggiungendo o rimuovendo qualsiasi elemento tranne il metodo remove () di Iterator. Ma questo non è un comportamento garantito e sarà fatto da JVM con il massimo sforzo. "

La mia fonte: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html


36

Oltre a tutti gli altri aspetti importanti già menzionati qui, l'API Collections (ad es. L'interfaccia della mappa) viene modificata continuamente per adeguarsi alle aggiunte "più recenti e migliori" alle specifiche Java.

Ad esempio, confronta Java 5 Map iterando:

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

rispetto al vecchio approccio Hashtable:

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

In Java 1.8 ci viene anche promesso di essere in grado di costruire e accedere a HashMap come in buoni vecchi linguaggi di scripting:

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

Aggiornamento: No, non atterreranno in 1.8 ... :(

I miglioramenti della collezione di Project Coin saranno in JDK8?


34

Hashtableè sincronizzato, mentre HashMapnon lo è. Questo rende Hashtablepiù lento di Hashmap.

Per le app senza thread, utilizzare HashMappoiché altrimenti sono le stesse in termini di funzionalità.


30
  • HashTable è sincronizzato, se lo si utilizza in un singolo thread è possibile utilizzare HashMap , che è una versione non sincronizzata. Gli oggetti non sincronizzati sono spesso un po 'più performanti. A proposito, se più thread accedono contemporaneamente a una HashMap e almeno uno dei thread modifica strutturalmente la mappa, deve essere sincronizzata esternamente. Puoi avvolgere una mappa non sincronizzata in una mappa sincronizzata usando:

    Map m = Collections.synchronizedMap(new HashMap(...));
  • HashTable può contenere solo oggetti non nulli come chiave o come valore. HashMap può contenere una chiave null e valori null.

  • Gli iteratori restituiti da Map sono fail-fast, se la mappa viene modificata strutturalmente in qualsiasi momento dopo la creazione dell'iteratore, in alcun modo tranne che attraverso il metodo di rimozione dell'iteratore stesso, l'iteratore genererà un ConcurrentModificationException. Pertanto, di fronte a modifiche simultanee, l'iteratore fallisce in modo rapido e pulito, piuttosto che rischiare un comportamento arbitrario e non deterministico in un momento indeterminato in futuro. Mentre le enumerazioni restituite dalle chiavi e dai metodi degli elementi di Hashtable non sono veloci.

  • HashTable e HashMap sono membri del Java Collections Framework (dalla piattaforma Java 2 v1.2, HashTable è stato adattato per implementare l'interfaccia Map).

  • HashTable è considerato codice legacy, la documentazione consiglia di utilizzare ConcurrentHashMap al posto di Hashtable se si desidera un'implementazione altamente concorrenziale thread-safe.

  • HashMap non garantisce l'ordine in cui vengono restituiti gli elementi. Per HashTable credo sia lo stesso, ma non sono del tutto sicuro, non trovo risorse che lo affermino chiaramente.


30

HashMape Hashtablehanno anche differenze algoritmiche significative. Nessuno lo ha mai menzionato prima, quindi è per questo che lo sto sollevando. HashMapcostruirà una tabella di hash con una potenza di due dimensioni, aumentandola in modo dinamico in modo da avere al massimo circa otto elementi (collisioni) in qualsiasi secchio e mescolerà gli elementi molto bene per i tipi di elementi generali. Tuttavia, l' Hashtableimplementazione fornisce un controllo migliore e più preciso sull'hash se si sa cosa si sta facendo, vale a dire che è possibile correggere la dimensione della tabella utilizzando, ad esempio, il numero primo più vicino alla dimensione del dominio dei valori e ciò comporterà prestazioni migliori rispetto a HashMap, ovvero meno collisioni per alcuni casi.

A parte le ovvie differenze discusse ampiamente in questa domanda, vedo l'Hashtable come un'auto a "guida manuale" in cui hai un migliore controllo sull'hashish e l'HashMap come la controparte di "azionamento automatico" che generalmente funzionerà bene.


27

Sulla base delle informazioni qui , consiglierei di utilizzare HashMap. Penso che il più grande vantaggio sia che Java ti impedirà di modificarlo mentre stai iterando su di esso, a meno che tu non lo faccia attraverso l'iteratore.


5
In realtà non lo impedisce, lo rileva e genera un errore.
Bart van Heukelom il

1
Sono abbastanza sicuro che genererà una ConncurrentModificationException prima che la raccolta sottostante venga modificata, anche se potrei sbagliarmi.
pkaeding

Esso tenta di rilevare modifiche simultaneo e un'eccezione. Ma se stai facendo qualcosa con i thread, non può fare alcuna promessa. Assolutamente può succedere di tutto, compresa la rottura .
cHao,

24

A Collection- a volte chiamato contenitore - è semplicemente un oggetto che raggruppa più elementi in una singola unità. Collectionvengono utilizzati per archiviare, recuperare, manipolare e comunicare dati aggregati. Un framework di raccolte W è un'architettura unificata per rappresentare e manipolare raccolte.

La HashMap JDK1.2e Hashtable JDK1.0, entrambi sono utilizzati per rappresentare un gruppo di oggetti che sono rappresentati in <Key, Value>coppia. Ogni <Key, Value>coppia è chiamata Entryoggetto. La raccolta di voci è indicata dall'oggetto di HashMape Hashtable. Le chiavi in ​​una raccolta devono essere uniche o distintive. [in quanto vengono utilizzati per recuperare un valore mappato una chiave particolare. i valori in una raccolta possono essere duplicati.]


« Membro di Superclass, Legacy e Collection Framework

Hashtable è una classe legacy introdotta in JDK1.0, che è una sottoclasse della classe Dictionary. Da JDK1.2Hashtable è stato riprogettato per implementare l' interfaccia Map per creare un membro del framework di raccolta. HashMap è un membro di Java Collection Framework sin dall'inizio della sua introduzione in JDK1.2. HashMap è la sottoclasse della 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à iniziale e fattore di carico

La capacità è il numero di bucket nella tabella hash e la capacità iniziale è semplicemente la capacità al momento della creazione della tabella hash. Si noti che la tabella hash è aperta: nel caso di un " hashcollision", un singolo bucket memorizza più voci, che devono essere ricercate in sequenza. Il fattore di carico è una misura della quantità massima consentita dalla tabella hash prima di aumentare automaticamente la sua capacità.

HashMap costruisce una tabella hash vuota con la capacità iniziale predefinita (16) e il fattore di carico predefinito (0,75). Dove come Hashtable costruisce hashtable vuoto con una capacità iniziale predefinita (11) e un fattore di carico / rapporto di riempimento (0,75).

Hash Map e Hashtable

« Modifica strutturale in caso di collisione dell'hash

HashMap, Hashtablein caso di collisioni hash memorizzano le voci della mappa in elenchi collegati. Da Java8 perHashMap se il bucket hash cresce oltre una certa soglia, il bucket passa da linked list of entries to a balanced tree. che migliorano le prestazioni nel caso peggiore da O (n) a O (log n). Durante la conversione dell'elenco in albero binario, l'hashcode viene utilizzato come variabile di ramificazione. Se ci sono due diversi hashcode nello stesso bucket, uno è considerato più grande e va a destra dell'albero e l'altro a sinistra. Ma quando entrambi gli hashcode sono uguali, HashMappresuppone che le chiavi siano comparabili e confronta la chiave per determinare la direzione in modo da mantenere un certo ordine. È buona norma rendere le chiavi HashMap comparabili . All'aggiunta di voci se la dimensione del bucket raggiungeTREEIFY_THRESHOLD = 8converte un elenco di voci collegate in un albero bilanciato, rimuovendo le voci meno TREEIFY_THRESHOLD e al massimo UNTREEIFY_THRESHOLD = 6riconvertirete un albero bilanciato in un elenco di voci collegato. Java 8 SRC , stackpost

« Raccolta iterazione, Fail-Fast e Fail-Safe

    +--------------------+-----------+-------------+
    |                    | Iterator  | Enumeration |
    +--------------------+-----------+-------------+
    | Hashtable          | fail-fast |    safe     |
    +--------------------+-----------+-------------+
    | HashMap            | fail-fast | fail-fast   |
    +--------------------+-----------+-------------+
    | ConcurrentHashMap  |   safe    |   safe      |
    +--------------------+-----------+-------------+

Iteratorè di natura fallimentare. ovvero genera ConcurrentModificationException se una raccolta viene modificata durante l'iterazione diversa dal proprio metodo remove (). Dove com'è a Enumerationprova di errore in natura. Non genera eccezioni se una raccolta viene modificata durante l'iterazione.

Secondo Java API Docs, Iterator è sempre preferito rispetto all'enumerazione.

NOTA: la funzionalità dell'interfaccia di enumerazione è duplicata dall'interfaccia Iterator. Inoltre, Iterator aggiunge un'operazione di rimozione facoltativa e ha nomi di metodo più brevi. Le nuove implementazioni dovrebbero prendere in considerazione l'utilizzo di Iterator rispetto all'enumerazione.

In Java 5 è stata introdotta l'interfaccia ConcurrentMap : ConcurrentHashMap- ConcurrentMapun'implementazione altamente concorrenziale e ad alte prestazioni supportata da una tabella hash. Questa implementazione non si blocca mai durante l'esecuzione di recuperi e consente al client di selezionare il livello di concorrenza per gli aggiornamenti. È inteso come un sostituto drop-in per Hashtable: oltre all'implementazione ConcurrentMap, supporta tutti i metodi "legacy" peculiari Hashtable.

  • Il HashMapEntryvalore di ogni s è volatile , garantendo così una consistenza a grana fine per le modifiche contestate e le letture successive; ogni lettura riflette l'aggiornamento completato più di recente

  • Iteratori ed enumerazioni sono Fail Safe - riflettendo lo stato ad un certo punto dalla creazione dell'iteratore / enumerazione; ciò consente letture e modifiche simultanee a scapito della coerenza ridotta. Non generano ConcurrentModificationException. Tuttavia, gli iteratori sono progettati per essere utilizzati da un solo thread alla volta.

  • Come Hashtablema diversamente HashMap, questa classe non consente l'utilizzo di null come chiave o valore.

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();
    }
}

« Null Keys e Null Values

HashMapconsente un massimo di una chiave null e qualsiasi numero di valori null. Dove as Hashtablenon consente nemmeno una singola chiave null e un valore null, se la chiave o il valore null è allora genera NullPointerException. Esempio

« Sincronizzato, thread-safe

Hashtableè sincronizzato internamente. Pertanto, è molto sicuro da usare Hashtablein applicazioni multi-thread. Dove as HashMapnon è sincronizzato internamente. Pertanto, non è sicuro utilizzare HashMapin applicazioni multi-thread senza sincronizzazione esterna. Puoi sincronizzare esternamente HashMapusando il Collections.synchronizedMap()metodo.

« Prestazioni

Come Hashtablesincronizzato internamente, questo rende Hashtableleggermente più lento di HashMap.


@Vedere


18

Per le app thread, puoi spesso cavartela con ConcurrentHashMap- dipende dai tuoi requisiti di prestazione.


17

1. Hashmape HashTablesia memorizza chiave e valore.

2. Hashmappuò memorizzare una chiave come null. Hashtablenon è possibile archiviare null.

3. HashMapnon è sincronizzato ma Hashtableè sincronizzato.

4. HashMappuò essere sincronizzato conCollection.SyncronizedMap(map)

Map hashmap = new HashMap();

Map map = Collections.SyncronizedMap(hashmap);

16

A parte le differenze già menzionate, va notato che dal momento che Java 8, HashMapsostituisce dinamicamente i Nodi (elenco collegato) utilizzati in ogni bucket con TreeNodes (albero rosso-nero), in modo che anche se esistono elevate collisioni di hash, il caso peggiore quando la ricerca è

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

* Il miglioramento summenzionato non è stato applicato ad Hashtableancora, ma solo HashMap, LinkedHashMape ConcurrentHashMap.

Cordiali saluti, attualmente,

  • TREEIFY_THRESHOLD = 8 : se un bucket contiene più di 8 nodi, l'elenco collegato viene trasformato in un albero bilanciato.
  • UNTREEIFY_THRESHOLD = 6 : quando un bucket diventa troppo piccolo (a causa della rimozione o del ridimensionamento) l'albero viene riconvertito in elenco collegato.

14

Esistono 5 differenze di base con HashTable e HashMaps.

  1. Maps ti consente di iterare e recuperare chiavi, valori ed entrambe le coppie chiave-valore, dove HashTable non ha tutte queste funzionalità.
  2. In Hashtable c'è una funzione contiene (), che è molto confusa da usare. Perché il significato di contiene è leggermente diverso. Indica se contiene chiave o contiene valore? difficile da capire. La stessa cosa in Maps abbiamo le funzioni ContainsKey () e ContainsValue (), che sono molto facili da capire.
  3. In hashmap puoi rimuovere l'elemento durante l'iterazione, in sicurezza. dove non è possibile negli hashtabili.
  4. Le tabelle hash sono sincronizzate per impostazione predefinita, quindi possono essere utilizzate facilmente con più thread. Dove come HashMaps non sono sincronizzati per impostazione predefinita, quindi possono essere utilizzati con un solo thread. Tuttavia, puoi ancora convertire HashMap in sincronizzato utilizzando la funzione synchronizedMap (Map m) di Collections util class.
  5. HashTable non consentirà chiavi o valori null. Dove come HashMap consente una chiave null e più valori null.

13

Il mio piccolo contributo:

  1. La prima e più significativa differenza tra Hashtablee HashMapè quella, HashMapnon è thread-safe mentre Hashtableè una collezione thread-safe.

  2. La seconda differenza importante tra Hashtablee HashMapè la prestazione, poiché HashMapnon è sincronizzata ma ha prestazioni migliori di Hashtable.

  3. La terza differenza su Hashtablevs HashMapè che Hashtableè una classe obsoleta e dovresti usare ConcurrentHashMapal posto di Hashtablein Java.


11

HashMap: è una classe disponibile all'interno del pacchetto java.util e viene utilizzata per memorizzare l'elemento in formato chiave e valore.

Hashtable: è una classe legacy che viene riconosciuta all'interno del framework di raccolta.


In tal caso, dovrebbe essere nei commenti e non come risposta.
manikant gautam,

10

HashTable è una classe legacy nel jdk che non dovrebbe più essere usata. Sostituisci gli utilizzi con ConcurrentHashMap . Se non hai bisogno della sicurezza dei thread, usa HashMap che non è sicuro per i thread ma più veloce e utilizza meno memoria.


Perché all'epoca pensavo che le altre risposte non respingessero HashTable ma spiegassero che era sicuro per il thread. La verità è che non appena vedi HashTable nel codice, dovresti sostituirlo con ConcurrentHashMap senza saltare un ritmo. E se la sicurezza dei thread non è un problema, HashMap può essere utilizzato per migliorare un po 'le prestazioni.
jontejj,

10
  1. Hashtableè sincronizzato mentre HashMapnon lo è.
  2. Un'altra differenza è che l'iteratore in HashMapè fail-safe mentre l'enumeratore per non lo Hashtableè. Se cambi la mappa durante l'iterazione, lo saprai.
  3. HashMapconsente valori nulli in esso, mentre Hashtablenon lo fa.

3
L'iteratore di HashMap è fail-fast, non fail-safe. Ecco perché abbiamo ConcurrentHashMap che consente la modifica durante l'iterazione. Controlla questo messaggio journaldev.com/122/…
Pankaj

9

HashMap e HashTable

  • Alcuni punti importanti su HashMap e HashTable. si prega di leggere i dettagli di seguito.

1) Hashtable e Hashmap implementano l'interfaccia java.util.Map 2) Sia Hashmap che Hashtable è la raccolta basata sull'hash. e lavorando su hashing. quindi queste sono somiglianze di HashMap e HashTable.

  • Qual è la differenza tra HashMap e HashTable?

1) La prima differenza è che HashMap non è thread-safe Mentre HashTable è ThreadSafe
2) HashMap offre prestazioni migliori perché non è thread-safe. mentre le prestazioni di Hashtable non sono migliori perché sono thread-safe. quindi più thread non possono accedere a Hashtable contemporaneamente.


2
Sotto votato perché questa risposta non è corretta in alcuni aspetti. Hashtable non implementa l'interfaccia Map, ma estende solo la classe Dictionary, che è obsoleta.
Yannis Sermetziadis,

8

Hashtable:

Hashtable è una struttura di dati che conserva i valori della coppia chiave-valore. Non consente null per entrambe le chiavi e i valori. Otterrai un valore NullPointerExceptionse aggiungi un valore null. È sincronizzato. Quindi viene con il suo costo. Solo un thread può accedere a HashTable in un determinato momento.

Esempio :

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 è come Hashtable ma accetta anche coppie chiave-valore. Permette null sia per le chiavi che per i valori. Le sue prestazioni sono migliori di HashTable, perché lo sono unsynchronized.

Esempio:

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));

    }
}

5

HashMapè emulato e quindi utilizzabile in GWT client codementre Hashtablenon lo è.


È una descrizione esaustiva delle differenze tra le due api?
IgorGanapolsky

Sì (sic!). Questo è tutto ciò che gli sviluppatori GWT devono sapere al riguardo.
pong

5

Argomento vecchio e classico, voglio solo aggiungere questo utile blog che spiega questo:

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

Blog di Manish Chhabra

Le 5 principali differenze tra HashMap e Hashtable

HashMap e Hashtable implementano entrambi l'interfaccia java.util.Map ma ci sono alcune differenze che gli sviluppatori Java devono comprendere per scrivere codice più efficiente. A partire dalla piattaforma Java 2 v1.2, la classe Hashtable è stata adattata per implementare l'interfaccia Map, rendendola membro del Java Collections Framework.

  1. Una delle principali differenze tra HashMap e Hashtable è che HashMap non è sincronizzato mentre Hashtable è sincronizzato, il che significa che Hashtable è thread-safe e può essere condiviso tra più thread ma HashMap non può essere condiviso tra più thread senza una corretta sincronizzazione. Java 5 ha introdotto ConcurrentHashMap che è un'alternativa di Hashtable e offre una migliore scalabilità rispetto a Hashtable in Java. Sincronizzato significa che solo un thread può modificare una tabella hash in un determinato momento. Fondamentalmente, significa che qualsiasi thread prima di eseguire un aggiornamento su una tabella hash dovrà acquisire un blocco sull'oggetto mentre altri aspetteranno il rilascio del blocco.

  2. La classe HashMap è approssimativamente equivalente a Hashtable, tranne per il fatto che consente valori null. (HashMap consente valori null come chiave e valore mentre Hashtable non consente valori null).

  3. La terza differenza significativa tra HashMap vs Hashtable è che Iterator in HashMap è un iteratore fail-fast mentre l'enumeratore per Hashtable non lo è e genera ConcurrentModificationException se qualsiasi altro thread modifica strutturalmente la mappa aggiungendo o rimuovendo qualsiasi elemento tranne Iterator stesso rimuovi ( ) metodo. Ma questo non è un comportamento garantito e sarà fatto da JVM con il massimo sforzo. Questa è anche una differenza importante tra Enumeration e Iterator in Java.

  4. Un'altra differenza notevole tra Hashtable e HashMap è che, a causa della sicurezza dei thread e della sincronizzazione, Hashtable è molto più lento di HashMap se utilizzato in un ambiente a thread singolo. Quindi, se non hai bisogno di sincronizzazione e HashMap viene utilizzato solo da un thread, esegue Hashtable in Java.

  5. HashMap non garantisce che l'ordine della mappa rimarrà costante nel tempo.

Nota che HashMap può essere sincronizzato da

Map m = Collections.synchronizedMap(hashMap);

Nel Riepilogo ci sono differenze significative tra Hashtable e HashMap in Java, ad es. Sicurezza dei thread e velocità e in base a ciò usa Hashtable solo se hai assolutamente bisogno della sicurezza dei thread, se stai eseguendo Java 5 considera l'utilizzo di ConcurrentHashMap in Java.


ConcurrentHashMap non è sincronizzato in lettura, mentre Hashtable lo è. Quindi, se hai un elevato numero di operazioni di lettura in corso contemporaneamente alle scritture, un Hashtable ti servirebbe meglio se ti preoccupi dell'integrità dei dati.
IgorGanapolsky

5

HashMap e Hashtable sono entrambi utilizzati per archiviare i dati in forma chiave e valore. Entrambi utilizzano la tecnica di hashing per memorizzare chiavi univoche. ma ci sono molte differenze tra le classi HashMap e Hashtable riportate di seguito.

inserisci qui la descrizione dell'immagine


Bel riassunto visivo!
Nadjib Mami,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.