ConcurrentMap
це не потрібно, оскільки в запитанні йдеться про "додатки без потоків", що означають, що нитка / паралельність не є проблемою.
ConcurrentMap
це не потрібно, оскільки в запитанні йдеться про "додатки без потоків", що означають, що нитка / паралельність не є проблемою.
Відповіді:
Існує кілька відмінностей між HashMap
та Hashtable
на Java:
Hashtable
буде синхронізовано , тоді як це HashMap
не так. Це робить HashMap
для додатків без потоків рівномірніші, оскільки несинхронізовані об'єкти зазвичай працюють краще, ніж синхронізовані.
Hashtable
не дозволяє null
ключі або значення. HashMap
дозволяє один null
ключ і будь-яку кількість null
значень.
Один з підкласів HashMap є LinkedHashMap
, таким чином , в тому випадку, якщо ви хочете передбачуваний порядок ітерації (що порядок вставки за замовчуванням), ви можете легко поміняти HashMap
для LinkedHashMap
. Це не було б так просто, якби ви користувались Hashtable
.
Оскільки синхронізація не є проблемою для вас, я б рекомендував HashMap
. Якщо синхронізація стає проблемою, ви також можете подивитися ConcurrentHashMap
.
Collections.synchronizedMap()
.
Hashtable
("синхронізація кожного методу повинен вирішувати будь-які проблеми з одночасністю!") Робить це дуже гіршим для потокових програм. Вам краще зовнішньо синхронізувати HashMap
(і думати про наслідки) або скористатися ConcurrentMap
реалізацією (та використовувати розширений API для одночасності). Підсумок: єдиною причиною для використання Hashtable
є те, коли потрібний застарілий API (приблизно з 1996 р.).
Зауважте, що багато відповідей стверджують, що Hashtable синхронізовано. На практиці це купує вам дуже мало. Синхронізація методами accessor / mutator зупинить два потоки додавання або видалення з карти одночасно, але в реальному світі вам часто потрібна додаткова синхронізація.
Дуже поширена ідіома - "перевірити, а потім поставити" - тобто шукати запис у Map
, і додавати його, якщо його ще немає. Це жодним чином не є атомною операцією, використовуєте ви Hashtable
чи HashMap
.
Еквівалентно синхронізований HashMap
може бути отриманий:
Collections.synchronizedMap(myMap);
Але для правильної реалізації цієї логіки потрібна додаткова синхронізація форми:
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
Навіть ітерація над Hashtable
записами 's (або HashMap
отримана за допомогою Collections.synchronizedMap
) не є безпечною для потоків, якщо ви також не захистите їх Map
від модифікації шляхом додаткової синхронізації.
Реалізації ConcurrentMap
інтерфейсу (наприклад ConcurrentHashMap
) вирішують щось із цього, включаючи безпечну потокову семантику check-then-act, наприклад:
ConcurrentMap.putIfAbsent(key, value);
Hashtable
вважається застарілим кодом. Нічого про Hashtable
це не можна зробити з використанням HashMap
або виведенням HashMap
, тому для нового коду я не бачу жодного виправдання для повернення до Hashtable
.
Це питання часто задають в інтерв'ю, щоб перевірити, чи розуміє кандидат правильне використання класів колекції та чи знає альтернативні варіанти.
HashMap
Клас приблизно відповідає Hashtable
, за винятком того, що вона не синхронізована і дозволяють нулі. ( HashMap
дозволяє нульові значення як ключ і значення, тоді як Hashtable
не дозволяє null
s).HashMap
не гарантує, що порядок карти залишатиметься незмінним у часі.HashMap
не синхронізований, тоді Hashtable
як синхронізований.HashMap
виходить з ладу, тоді як нумератор Hashtable
не є і кидає, ConcurrentModificationException
якщо будь-який інший потік структурно змінює карту, додаючи або видаляючи будь-який елемент, крім Iterator
власного remove()
методу. Але це не є гарантованою поведінкою, і СП буде виконувати все можливе.Примітка про деякі важливі умови:
Hashtable
повинен буде придбати замок на об'єкті, тоді як інші чекатимуть звільнення блокування.set
метод, оскільки він не модифікує колекцію "структурно". Однак, якщо до виклику set
колекцію структурно модифікували, IllegalArgumentException
вона буде кинута.HashMap
може бути синхронізовано
Map m = Collections.synchronizeMap(hashMap);
Карта забезпечує перегляди колекції замість прямої підтримки ітерації через об'єкти перерахування. Перегляди колекції значно підвищують виразність інтерфейсу, про що йдеться далі в цьому розділі. Карта дозволяє переглядати ключі, значення або пари ключів і значень;
Hashtable
не передбачає третього варіанту. Карта забезпечує безпечний спосіб видалення записів у розпал ітерації; Hashtable
не. Нарешті, Map виправляє незначний недолік в Hashtable
інтерфейсі.
Hashtable
має метод, який називається містить, який повертає істину, якщо
Hashtable
містить задане значення. З огляду на його ім'я, можна було очікувати , цей метод повертає істину , якщо Hashtable
містить заданий ключ, оскільки ключ є основним механізмом доступу для Hashtable
. Інтерфейс Map усуває це джерело плутанини шляхом перейменування методу
containsValue
. Також це покращує послідовність інтерфейсу -
containsValue
паралелі containsKey
.
set
операції на a HashMap
. 3) put(...)
Операція не кинеться, IllegalArgumentException
якщо відбулася попередня зміна. 4) Невдала поведінка системи HashMap
також виникає, якщо змінити відображення. 5) Нерабочий-швидко поведінку буде гарантовано. (Що не гарантується, це поведінка, HashTable
якщо ви робите одночасну модифікацію. Фактична поведінка ... непередбачувана.)
Hashtable
не гарантує, що порядок елементів карти також буде стабільним у часі. (Ви , можливо , плутаючи Hashtable
з LinkedHashMap
.)
thing.set(thing.get() + 1);
яке частіше за все ловить новачків зненацька, як абсолютно незахищений, особливо якщо це get()
і set()
є синхронізованими методами. Багато з них очікують магії.
HashMap
: Реалізація Map
інтерфейсу, який використовує хеш-коди для індексації масиву.
Hashtable
: Привіт, 1998 р. Зателефонував. Вони хочуть повернути API своїх колекцій.
Якщо серйозно, то вам краще Hashtable
взагалі не триматися подалі . Для однопотокових програм вам не потрібні додаткові накладні витрати на синхронізацію. Для програм, що ведуть одночасне використання, параноїдальна синхронізація може призвести до голоду, тупиків або непотрібних пауз з вивезенням сміття. Як зазначив Тім Хоуланд, ви можете використовувати це ConcurrentHashMap
замість цього.
Майте на увазі, що це HashTable
було старим класом до впровадження Java Collections Framework (JCF) і пізніше було оновлено для реалізації Map
інтерфейсу. Так було Vector
і Stack
.
Тому завжди тримайтеся подалі від них у новому коді, оскільки в JCF завжди є краща альтернатива, як вказували інші.
Ось чіт-лист колекції Java, який ви знайдете корисним. Зауважте, сірий блок містить застарілий клас HashTable, Vector та Stack.
Тут вже багато хороших відповідей. Я додаю кілька нових пунктів і резюмую.
HashMap
і Hashtable
обидва використовуються для зберігання даних у формі ключа та значення . Обидва використовують техніку хешування для зберігання унікальних ключів. Але існує багато відмінностей між класами HashMap і Hashtable, які наведені нижче.
HashMap
HashMap
не синхронізовано. Він не є безпечним для потоків і не може ділитися між багатьма потоками без належного коду синхронізації. HashMap
дозволяє один нульовий ключ і кілька нульових значень. HashMap
це новий клас, представлений в JDK 1.2. HashMap
швидко. HashMap
як синхронізований, викликаючи цей кодMap m = Collections.synchronizedMap(HashMap);
HashMap
проходить Ітератор. HashMap
не працює. HashMap
успадковує клас AbstractMap. Хешбел
Hashtable
синхронізовано. Він безпечний для потоків і може бути спільним для багатьох потоків. Hashtable
не допускає жодного нульового ключа або значення. Hashtable
це клас спадщини. Hashtable
повільно. Hashtable
внутрішньо синхронізований і не може бути синхронізований. Hashtable
проходить шляхом перечислювача та ітератора. Hashtable
не є швидким. Hashtable
успадковує клас словника.Подальше читання Яка різниця між HashMap та Hashtable у Java?
Окрім того, що izb сказав, HashMap
допускає нульові значення, тоді як значення Hashtable
цього немає.
Також зауважте, що Hashtable
розширення Dictionary
класу, який як стан Javadocs , є застарілим і його замінив Map
інтерфейс.
Погляньте на цю діаграму. Він забезпечує порівняння між різними структурами даних разом із HashMap
та Hashtable
. Порівняння точне, чітке і легко зрозуміле.
Hashtable
подібний до HashMap
та має аналогічний інтерфейс. Рекомендується використовувати HashMap
, якщо вам не потрібна підтримка застарілих програм або вам потрібна синхронізація, оскільки Hashtables
методи синхронізовані. Тож у вашому випадку, оскільки ви не багатопоточні, HashMaps
найкраща ставка.
Ще одна ключова відмінність хешбюля від хешмапу полягає в тому, що Iterator в HashMap є невдалим, тоді як нумератор для Hashtable не є і кидає ConcurrentModificationException, якщо будь-який інший Thread змінює карту структурно, додаючи або видаляючи будь-який елемент, крім власного методу delete () Iterator. Але це не є гарантованою поведінкою, і СП буде виконувати все можливе ".
Моє джерело: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
Окрім усіх інших важливих аспектів, про які вже говорилося тут, API колекцій (наприклад, інтерфейс карти) постійно змінюється, щоб відповідати "останнім і найбільшим" доповненням до специфікації Java.
Наприклад, порівняйте ітерацію карти Java 5:
for (Elem elem : map.keys()) {
elem.doSth();
}
проти старого підходу Hashtable:
for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
Elem elem = (Elem) en.nextElement();
elem.doSth();
}
У Java 1.8 нам також обіцяють створити та отримати доступ до HashMaps, як у старих хороших мовах сценаріїв:
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
Оновлення: Ні, вони не приземляться через 1.8 ... :(
HashTable синхронізований, якщо ви використовуєте його в одному потоці, ви можете використовувати HashMap , який є несинхронізованою версією. Несинхронізовані об'єкти часто трохи ефективніші. До речі, якщо кілька потоків отримують доступ до HashMap одночасно, і принаймні один з потоків структурно модифікує карту, вона повинна бути синхронізована зовні. Неможливо синхронізувати карту в синхронізовану за допомогою:
Map m = Collections.synchronizedMap(new HashMap(...));
HashTable може містити лише ненульовий об'єкт як ключ або як значення. HashMap може містити один нульовий ключ і нульові значення.
Ітератори, повернені Map, невдалі, якщо карта структурно модифікована в будь-який час після створення ітератора, будь-яким способом, за винятком власного методу видалення ітератора, ітератор видалить ConcurrentModificationException
. Таким чином, в умовах одночасних модифікацій ітератор виходить з ладу швидко і чисто, замість того, щоб ризикувати довільною недетермінованою поведінкою у невизначений час у майбутньому. Тоді як перерахування, повернені ключами та методами елементів Hashtable, не є швидкими.
HashTable і HashMap є членами Java Collections Framework (оскільки платформа Java 2 v1.2, HashTable була дооснащена для реалізації інтерфейсу Map).
HashTable вважається застарілим кодом, документація радить використовувати ConcurrentHashMap замість Hashtable, якщо потрібна безпечна для потоків реалізація.
HashMap не гарантує порядок повернення елементів. Для HashTable я думаю, що це те саме, але я не зовсім впевнений, я не знаходжу ресурс, який би це чітко зазначив.
HashMap
і Hashtable
мають значні алгоритмічні відмінності. Ніхто раніше не згадував про це, тому я і виховую це. HashMap
побудує хеш-таблицю потужністю в два розміри, динамічно збільшить її, щоб у вас було щонайменше близько восьми елементів (зіткнень) у будь-якому відрі і дуже добре перемішав би елементи для загальних типів елементів. Однак Hashtable
реалізація забезпечує кращий і точніший контроль над хешированием, якщо ви знаєте, що ви робите, а саме ви можете виправити розмір таблиці, використовуючи, наприклад, найближчий простий номер до вашого розміру домену значень, і це призведе до кращої продуктивності, ніж HashMap, тобто менше зіткнень для деяких випадків.
Окремо від очевидних розбіжностей, обговорених широко в цьому питанні, я бачу Hashtable як автомобіль з "ручним приводом", де ви краще контролюєте хеширование та HashMap як аналог "автоматичного приводу", який, як правило, справляється добре.
Виходячи з інформації тут , я рекомендую перейти з HashMap. Я думаю, що найбільша перевага полягає в тому, що Java заважатиме вам змінювати її під час ітерації над нею, якщо ви не зробите це через ітератор.
А Collection
- іноді називається контейнером - це просто об'єкт, який групує кілька елементів в одну одиницю. Collection
s використовуються для зберігання, пошуку, маніпулювання та передачі сукупних даних. Рамка колекцій W - це єдина архітектура для представлення та маніпулювання колекціями.
HashMap
JDK1.2
І Hashtable JDK1.0
, і використовується для представлення групи об'єктів, які представлені в <Key, Value>
парі. Кожна <Key, Value>
пара називається Entry
об'єктом. Збірник записів посилається на об'єкт HashMap
і Hashtable
. Ключі в колекції повинні бути унікальними або відмінними. [як вони використовуються для отримання відображеного значення певного ключа. значення в колекції можна дублювати.]
« Член Рамкового рівня, Спадщини та Колекції
Hashtable - це введений у спадщину клас JDK1.0
, який є підкласом класу Словник. Від JDK1.2
Hashtable реінжинірований для реалізації інтерфейсу Map, щоб зробити членом колекції рамки. HashMap є членом Java Collection Framework з самого початку її впровадження в JDK1.2
. HashMap - це підклас класу 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 { ... }
« Початкова потужність і коефіцієнт навантаження
Ємність - це кількість відро в хеш-таблиці, а початкова ємність - просто ємність у момент створення хеш-таблиці. Зауважте, що хеш-таблиця відкрита: у випадку " hash
collision
" одного відра зберігає кілька записів, які необхідно шукати послідовно. Коефіцієнт навантаження - це міра того, наскільки дозволено отримати хеш-таблицю до автоматичного збільшення її ємності.
HashMap створює порожню хеш-таблицю з початковою ємністю за замовчуванням (16) та коефіцієнтом навантаження за замовчуванням (0,75). Де, як Hashtable будує порожній хешбел із початковою ємністю за замовчуванням (11) та коефіцієнтом завантаження / коефіцієнтом заповнення (0,75).
« Структурна модифікація на випадок зіткнення хешу
HashMap
, Hashtable
у випадку зіткнення хешу вони зберігають записи карти у пов'язаних списках. З Java8,HashMap
якщо хеш-відро зростає за певний поріг, з цього відра вимкнетьсяlinked list of entries to a balanced tree
. які покращують найгірші показники від O (n) до O (log n). Під час перетворення списку у двійкове дерево, хеш-код використовується як змінна гілка. Якщо в одному відрі є два різних хеш-коди, один вважається більшим і йде праворуч від дерева, а інший - зліва. Але коли обидва хеш-коди рівні, HashMap
передбачається, що ключі порівнянні, і порівнює ключ для визначення напрямку, щоб можна було підтримувати певний порядок. Це хороша практика зробити ключі HashMap
порівнянними . Додавання записів, якщо розмір відра досягаєTREEIFY_THRESHOLD = 8
перетворити зв'язаний список записів у збалансоване дерево, при видаленні записів менше TREEIFY_THRESHOLD
і щонайменше UNTREEIFY_THRESHOLD = 6
поверне збалансоване дерево у пов'язаний список записів. Java 8 SRC , стекпост
« Ітерація перегляду колекції, Fail-Fast і Fail-Safe
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iterator
є невдалим характером. тобто він кидає ConcurrentModificationException, якщо колекцію модифікують під час ітерації, відмінного від власного методу delete (). Там, де Enumeration
це безпечно відмови. Він не кидає жодних винятків, якщо колекція модифікується під час ітерації.
Згідно з Java API Docs, Iterator завжди перевага перед перерахуванням.
ПРИМІТКА . Функціонал інтерфейсу перерахування дублюється інтерфейсом Iterator. Крім того, Iterator додає необов'язкову операцію видалення та має більш короткі назви методів. Новим реалізаціям слід розглянути можливість використання Iterator у перевазі «Перерахування».
В Java 5 представлений ConcurrentMap Interface : ConcurrentHashMap
- високо одночасне, високоефективне ConcurrentMap
реалізація, підкріплене хеш-таблицею. Ця реалізація ніколи не блокується під час пошуку і дозволяє клієнту вибрати рівень одночасності оновлень. Він призначений як заміна заміни для Hashtable
: окрім впровадження ConcurrentMap
, він підтримує всі властивості "спадщини" Hashtable
.
Кожне HashMapEntry
значення s є непостійним, завдяки чому забезпечується тонкодисперсна зернистість для заявлених модифікацій та наступних зчитувань; кожне прочитане відображає останнє завершене оновлення
Ітератори та перерахування є безпечними для відмов - відображають стан у певний момент з моменту створення ітератора / перерахування; це дозволяє одночасно читати та модифікувати ціною зниженої послідовності. Вони не кидають ConcurrentModificationException. Однак ітератори призначені для використання лише однією ниткою за один раз.
Як Hashtable
і на відміну від HashMap
цього, цей клас не дозволяє використовувати null як ключ або значення.
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();
}
}
« Нульові ключі та нульові значення
HashMap
дозволяє максимально один нульовий ключ і будь-яку кількість нульових значень. Де як Hashtable
не дозволяє навіть один нульовий ключ і нульове значення, якщо ключ або значення null, то він кидає NullPointerException. Приклад
« Синхронізована, безпечна для потоків
Hashtable
внутрішньо синхронізований. Тому використовувати його Hashtable
в багатопотокових програмах дуже безпечно . Де як HashMap
внутрішньо не синхронізовано. Тому використання HashMap
в багатопотокових програмах без зовнішньої синхронізації не є безпечним . Ви можете зовнішньо синхронізувати HashMap
за допомогою Collections.synchronizedMap()
методу.
« Виступ
Як Hashtable
це внутрішньо синхронізовано, це робить Hashtable
трохи повільніше, ніж HashMap
.
@Подивитися
Для потокових програм ви можете часто піти з ConcurrentHashMap - це залежить від ваших вимог щодо продуктивності.
1. Hashmap
і HashTable
ключ зберігання, і значення.
2. Hashmap
може зберігати один ключ як null
. Hashtable
не можна зберігати null
.
3. HashMap
не синхронізований, але Hashtable
синхронізований.
4. HashMap
можуть бути синхронізовані зCollection.SyncronizedMap(map)
Map hashmap = new HashMap();
Map map = Collections.SyncronizedMap(hashmap);
Крім відмінностей, про які вже згадувалося, слід зазначити, що оскільки Java 8 HashMap
динамічно замінює Вузли (зв'язаний список), що використовуються у кожному відрі, TreeNodes (червоно-чорне дерево), так що навіть при великих зіткненнях хешу, найгірший випадок, коли пошук є
O (log (n)) для HashMap
Vs O (n) в Hashtable
.
* Вищезазначене поліпшення не застосовується до Hashtable
ще, але тільки HashMap
, LinkedHashMap
і ConcurrentHashMap
.
На даний момент,
TREEIFY_THRESHOLD = 8
: якщо відро містить більше 8 вузлів, пов'язаний список перетворюється на збалансоване дерево.UNTREEIFY_THRESHOLD = 6
: коли відро стає занадто малим (через видалення чи зміну розміру) дерево перетворюється назад у пов'язаний список.Існує 5 основних диференціацій з HashTable і HashMaps.
Мій невеликий внесок:
Перше і найзначніше розрізнялися
Hashtable
і вHashMap
тому , що,HashMap
НЕ поточно-то часHashtable
є поточно-колекція.Друга важлива відмінність між
Hashtable
іHashMap
- це продуктивність, оскількиHashMap
не синхронізована, вона працює краще, ніжHashtable
.Третя відмінність від
Hashtable
vsHashMap
полягає в тому, щоHashtable
це застарілий клас, і його слід використовуватиConcurrentHashMap
замістьHashtable
Java.
HashMap: Це клас, доступний у пакеті java.util, і він використовується для зберігання елемента у форматі ключа та значення.
Хешбел: Це спадковий клас, який розпізнається в рамках колекції.
HashTable - це застарілий клас у jdk, який більше не слід використовувати. Замініть звичаї його на ConcurrentHashMap . Якщо вам не потрібна безпека потоку, використання HashMap , який не є поточно , але швидше і використовує менше пам'яті.
Hashtable
синхронізовано, тоді HashMap
як ні.HashMap
безпечний", тоді як нумератор Hashtable
- не. Якщо ви зміните карту під час ітерації, ви знаєте.HashMap
дозволяє в ньому нульові значення, а Hashtable
ні.HashMap і HashTable
1) Hashtable і Hashmap реалізують інтерфейс java.util.Map 2) І Hashmap, і Hashtable - це колекція на основі хеш-файлів. і робота над хешированием. так це схожість HashMap і HashTable.
1) Перша відмінність HashMap не є безпечною для потоків. Хоча HashTable є ThreadSafe
2) HashMap ефективніше, оскільки вона не є безпечною для потоків. в той час, як продуктивність Hashtable не є кращою, оскільки безпечна для потоків. тому декілька потоків не можуть одночасно отримати доступ до Hashtable.
Hashtable:
Хештеб - це структура даних, яка зберігає значення пари ключ-значення. Це не дозволяє нулю і для клавіш, і для значень. Ви отримаєте, NullPointerException
якщо додасте нульове значення. Він синхронізований. Тож воно йде зі своєю вартістю. Лише один потік може отримати доступ до HashTable в певний час.
Приклад :
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 схожий на Hashtable, але він також приймає пару ключових значень. Це дозволяє нулю як для клавіш, так і для значень. Його ефективність краща, ніж HashTable
, бо вона є unsynchronized
.
Приклад:
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));
}
}
HashMap
емулюється і тому може бути використаний у GWT client code
той час як Hashtable
це не так.
Стара і класична тема, просто хочу додати цей корисний блог, який пояснює це:
http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/
Блог Маніш Чхабра
5 основних відмінностей між HashMap і Hashtable
І HashMap, і Hashtable реалізують інтерфейс java.util.Map, але є деякі відмінності, які розробники Java повинні розуміти, щоб написати більш ефективний код. Станом на платформі Java 2 v1.2 клас Hashtable був модернізований для реалізації інтерфейсу Map, завдяки чому він став членом Java Collections Framework.
Однією з головних відмінностей між HashMap і Hashtable є те, що HashMap не синхронізований, тоді як Hashtable є синхронізованим, що означає, що Hashtable є безпечним для потоків і може бути розділений між декількома потоками, але HashMap не може бути розподілений між декількома потоками без належної синхронізації. Java 5 представила ConcurrentHashMap, який є альтернативою Hashtable і забезпечує кращу масштабованість, ніж Hashtable в Java. Синхронізований означає, що лише один потік може змінювати хеш-таблицю в один момент часу. В основному це означає, що будь-який потік перед виконанням оновлення на хештелі повинен буде придбати замок на об'єкті, а інші чекатимуть звільнення блокування.
Клас HashMap приблизно еквівалентний Hashtable, за винятком того, що він дозволяє нулі. (HashMap дозволяє нульові значення як ключові та значення, тоді як Hashtable не дозволяє нульових значень).
Третя суттєва відмінність HashMap від Hashtable полягає в тому, що Iterator в HashMap є невдалим ітератором, тоді як нумератор для Hashtable не є і не кидає ConcurrentModificationException, якщо будь-яка інша нитка змінює карту структурно, додаючи або видаляючи будь-який елемент, крім власного видалення Iterator ( ) метод. Але це не є гарантованою поведінкою, і СП буде виконувати все можливе. Це також важлива різниця між перерахуванням та ітератором на Java.
Ще одна помітна відмінність між Hashtable і HashMap полягає в тому, що через безпеку потоків і синхронізацію Hashtable набагато повільніше, ніж HashMap, якщо він використовується в середовищі з одиночним потоком. Отже, якщо вам не потрібна синхронізація, а HashMap використовується лише одним потоком, він виконує Hashtable на Java.
HashMap не гарантує, що порядок карти залишатиметься постійним у часі.
Зауважте, що HashMap можна синхронізувати за допомогою
Map m = Collections.synchronizedMap(hashMap);
Підсумовуючи істотні відмінності між Hashtable і HashMap на Java, наприклад, безпека потоку та швидкість, і на основі цього використовуйте Hashtable лише тоді, коли вам абсолютно потрібна безпека потоку, якщо ви працюєте з Java 5, розгляньте можливість використання ConcurrentHashMap в Java.
І HashMap, і Hashtable використовуються для зберігання даних у формі ключа та значення. Обидва використовують техніку хешування для зберігання унікальних ключів. ut Є багато відмінностей між класами HashMap і Hashtable, які наведені нижче.