Перейти к основному содержимому

Различия между HashMap и Hashtable

· 3 мин. чтения

1. Обзор

В этом коротком руководстве мы сосредоточимся на основных различиях между Hashtable и HashMap .

2. Hashtable и HashMap в Java

Hashtable и HashMap очень похожи — обе коллекции реализуют интерфейс Map .

Кроме того, методы put() , get() , remove() и containsKey() обеспечивают производительность O(1) с постоянным временем. Внутри эти методы работают на основе общей концепции хеширования с использованием сегментов для хранения данных.

Ни один из классов не поддерживает порядок вставки элементов. Другими словами, первый добавленный элемент может не быть первым элементом, когда мы перебираем значения.

Но у них также есть некоторые различия, которые делают один лучше другого в некоторых ситуациях. Давайте рассмотрим эти различия поближе.

3. Различия между Hashtable и HashMap

3.1. Синхронизация

Во- первых, Hashtable является потокобезопасным и может совместно использоваться несколькими потоками в приложении.

С другой стороны, HashMap не синхронизируется и не может быть доступен нескольким потокам без дополнительного кода синхронизации. Мы можем использовать Collections.synchronizedMap() для создания потокобезопасной версии HashMap . Мы также можем просто создать собственный код блокировки или сделать код потокобезопасным, используя ключевое слово synchronized .

HashMap не синхронизируется, поэтому он быстрее и использует меньше памяти, чем Hashtable . Как правило, несинхронизированные объекты работают быстрее, чем синхронизированные, в однопоточном приложении.

3.2. Нулевые значения

Другим отличием является нулевая обработка. HashMap позволяет добавить одну запись с нулем в качестве ключа, а также множество записей с нулем в качестве значения. Напротив, Hashtable вообще не допускает null . Давайте посмотрим на пример null и HashMap :

HashMap<String, String> map = new HashMap<String, String>();
map.put(null, "value");
map.put("key1", null);
map.put("key2", null);

Это приведет к:

assertEquals(3, map.size());

Далее давайте посмотрим, чем отличается Hashtable:

Hashtable<String, String> table = new Hashtable<String, String>();
table.put("key", null);

Это приводит к исключению NullPointerException . Добавление объекта с нулевым ключом также приводит к исключению NullPointerException :

table.put(null, "value");

3.3. Итерация по элементам

HashMap использует Iterator для перебора значений, тогда как Hashtable имеет Enumerator для того же. Iterator является преемником Enumerator , который устраняет его несколько недостатков. Например, у Iterator есть метод remove() для удаления элементов из базовых коллекций.

Iterator — отказоустойчивый итератор . Другими словами, он генерирует исключение ConcurrentModificationException , когда базовая коллекция изменяется во время итерации. Давайте посмотрим на пример отказоустойчивости: ``

HashMap<String, String> map = new HashMap<String, String>();
map.put("key1", "value1");
map.put("key2", "value2");

Iterator<String> iterator = map.keySet().iterator();
while(iterator.hasNext()){
iterator.next();
map.put("key4", "value4");
}

Это вызывает исключение ConcurrentModificationException , потому что мы вызываем put() во время итерации по коллекции.

4. Когда выбирать HashMap вместо Hashtable ``

Мы должны использовать HashMap для несинхронизированного или однопоточного приложения.

Стоит отметить, что начиная с JDK 1.8 Hashtable устарела. Однако ConcurrentHashMap — отличная замена Hashtable . Мы должны рассмотреть ConcurrentHashMap для использования в приложениях с несколькими потоками.

5. Вывод

В этой статье мы проиллюстрировали различия между HashMap и Hashtable и то, что нужно иметь в виду, когда нам нужно выбрать один из них.

Как обычно, реализация всех этих примеров и фрагментов кода закончена на Github .