A Collection- czasami nazywany kontenerem - to po prostu obiekt, który grupuje wiele elementów w jedną jednostkę. CollectionS są używane do przechowywania, pobierania, manipulowania i komunikowania danych agregowanych. Struktura kolekcji W to ujednolicona architektura do reprezentowania kolekcji i manipulowania nimi.
HashMap JDK1.2I HashTable JDK1.0zarówno stosuje się do oznaczania grup przedmiotów, które są reprezentowane w <Key, Value>pary. Każda <Key, Value>para nazywa się Entryobiektem. Zbiór wpisów jest określany przez obiekt HashMapi Hashtable. Klucze w kolekcji muszą być unikalne lub charakterystyczne. [ponieważ są używane do pobierania zamapowanej wartości określonego klucza. wartości w kolekcji można powielić.]
« Członek Superclass, Legacy and Collection Framework
Hashtable to wprowadzona w starszej klasie klasa JDK1.0, która jest podklasą klasy Dictionary. From JDK1.2Hashtable został przeprojektowany do implementacji interfejsu Map, aby stać się członkiem frameworka kolekcji. HashMap jest członkiem Java Collection Framework od samego początku jego wprowadzenia JDK1.2. HashMap jest podklasą klasy 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 { ... }
« Początkowa wydajność i współczynnik obciążenia
Pojemność to liczba segmentów w tabeli skrótów, a początkowa pojemność to po prostu pojemność w momencie tworzenia tabeli skrótów. Zauważ, że tabela skrótów jest otwarta: w przypadku „ hashcollision” pojedyncze wiadro przechowuje wiele wpisów, które należy kolejno przeszukiwać. Współczynnik obciążenia jest miarą tego, jak pełne jest wypełnienie tabeli mieszającej, zanim jej pojemność zostanie automatycznie zwiększona.
HashMap tworzy pustą tablicę skrótów z domyślną początkową pojemnością (16) i domyślnym współczynnikiem obciążenia (0,75). Gdzie as Hashtable konstruuje pusty hashtable z domyślną pojemnością początkową (11) i współczynnikiem obciążenia / wypełnienia (0,75).

« Modyfikacja strukturalna w przypadku zderzenia mieszającego
HashMap, Hashtablew przypadku kolizji skrótu przechowują wpisy map na połączonych listach. Z Java8,HashMap jeśli wiadro skrótu przekroczy określony próg, to wiadro się zmieni linked list of entries to a balanced tree. które poprawiają wydajność najgorszego przypadku od O (n) do O (log n). Podczas konwertowania listy na drzewo binarne kod skrótu jest używany jako zmienna rozgałęziająca. Jeśli w tym samym wiadrze znajdują się dwa różne kody skrótu, jeden jest uważany za większy i idzie na prawo od drzewa, a drugi na lewo. Ale gdy oba kody HashMapskrótu są równe, zakłada, że klucze są porównywalne, i porównuje klucz w celu ustalenia kierunku, aby zachować pewną kolejność. Dobrą praktyką jest HashMap porównywanie kluczy . Po dodaniu wpisów, jeśli osiągnie rozmiar wiadraTREEIFY_THRESHOLD = 8przekonwertuj połączoną listę wpisów na zrównoważone drzewo, po usunięciu wpisów mniej niżTREEIFY_THRESHOLD i co najwyżej UNTREEIFY_THRESHOLD = 6przekształci zrównoważone drzewo w połączoną listę wpisów. Java 8 SRC , stosu
« Iteracja widoku kolekcji, Fast-Fast i Fail-Safe
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iteratorjest z natury szybki w działaniu. tzn. zgłasza ConcurrentModificationException, jeśli kolekcja jest modyfikowana podczas iteracji innej niż jej własna metoda remove (). Gdzie Enumerationz natury jest bezpieczny w razie awarii. Nie rzuca żadnych wyjątków, jeśli kolekcja jest modyfikowana podczas iteracji.
Zgodnie z dokumentacją Java API Docs, Iterator jest zawsze preferowany niż wyliczanie.
UWAGA: Funkcjonalność interfejsu wyliczania jest zduplikowana przez interfejs Iteratora. Ponadto Iterator dodaje opcjonalną operację usuwania i ma krótsze nazwy metod. Nowe implementacje powinny rozważyć użycie Iteratora zamiast opcji Wyliczanie.
W Javie 5 wprowadzono interfejs ConcurrentMap : ConcurrentHashMap- wysoce współbieżna, wysokowydajna ConcurrentMapimplementacja wspierana przez tablicę skrótów. Ta implementacja nigdy nie blokuje się podczas pobierania danych i pozwala klientowi wybrać poziom współbieżności dla aktualizacji. Ma on zastąpić drop-in dla Hashtable: oprócz implementacji ConcurrentMap, obsługuje wszystkie specyficzne dla niego „starsze” metody Hashtable.
Każda HashMapEntrywartość jest lotna, zapewniając w ten sposób drobną spójność ziarna dla spornych modyfikacji i kolejnych odczytów; każdy odczyt odzwierciedla najnowszą ukończoną aktualizację
Iteratory i wyliczenia są bezpieczne w razie awarii - odzwierciedlając stan w pewnym momencie od utworzenia iteratora / wyliczenia; pozwala to na jednoczesne odczyty i modyfikacje kosztem zmniejszonej spójności. Nie zgłaszają wyjątku ConcurrentModificationException. Jednak iteratory są zaprojektowane do użycia tylko przez jeden wątek na raz.
Podobnie, Hashtableale w przeciwieństwie do HashMaptej klasy, nie pozwala na użycie wartości null jako klucza lub wartości.
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();
}
}
« Klucze zerowe i wartości zerowe
HashMapdopuszcza maksymalnie jeden klucz zerowy i dowolną liczbę wartości zerowych. Gdzie as Hashtablenie zezwala nawet na pojedynczy klucz zerowy i zerową wartość, jeśli klucz lub wartość zerowa jest, wówczas zgłasza wyjątek NullPointerException. Przykład
« Zsynchronizowany, bezpieczny dla wątków
Hashtablejest wewnętrznie zsynchronizowany. Dlatego bardzo bezpieczne jest stosowanie Hashtablew aplikacjach wielowątkowych. Gdzie HashMapnie jest wewnętrznie zsynchronizowany. Dlatego stosowanie HashMapw aplikacjach wielowątkowych bez zewnętrznej synchronizacji nie jest bezpieczne . Możesz zewnętrznie synchronizować HashMapza pomocą Collections.synchronizedMap()metody.
« Wydajność
Ponieważ Hashtablejest zsynchronizowany wewnętrznie, powoduje to, że jest Hashtablenieco wolniejszy niż HashMap.
@Widzieć