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

« 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