Разница между HashMap и Hashtable в Java

На начальном уровне Java-программиста вы можете ожидать этот вопрос на собеседовании по Hashtable против HashMap. Хотя вопрос становится действительно простым, когда вы знаете другие концепции, например, как работает hashmap, все же после получения множества вопросов от читателей моего блога, которые готовятся или работают на уровне junior, я решил обобщить свои знания о различиях между HashMap и Hashtable.

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

1.1 Синхронизация

Hashtable синхронизирован(т.е. методы определены внутри Hashtable), тогда как HashMap — нет. Если вы хотите сделать HashMap потокобезопасным, используйте класс Collections.synchronizedMap(map) или ConcurrentHashMap.

Методы внутри HashTable определяются синхронизированно, как показано ниже:

public synchronized boolean contains(Object obj){ ... }public synchronized boolean containsKey(Object obj){ ... }public synchronized Object get(Object obj){ ... }public synchronized Object put(Object obj, Object obj1){ ... }public synchronized Object remove(Object obj){ ... }

1.2.Нулевые ключи

Hashtable не допускает нулевых ключей или значений. HashMap допускает один нулевой ключ(другие нулевые ключи просто перезапишут первый нулевой ключ) и любое количество нулевых значений.

Hashtable<String, String> hashTable = new Hashtable<String, String>();hashTable.put(null, "value");//ORhashTable.put("key", null);Output:Exception in thread "main" java.lang.NullPointerExceptionat java.util.Hashtable.hash(Unknown Source)at java.util.Hashtable.put(Unknown Source)at test.core.MapExamples.main(MapExamples.java:12)

1.3 Наследие

Hashtable — устаревший класс, не входивший в состав первоначального Java Collections Framework(позже он был включен в JDK 1.2). HashMap является частью Collections с момента его появления. Также обратите внимание, что Hashtable расширяет класс Dictionary, который, как указано в Javadocs, устарел и был заменен интерфейсом Map в новых версиях JDK.

//HashTable is defined aspublic class Hashtable extends Dictionary implements Map, Cloneable, Serializable {}//HashMap is defined aspublic class HashMap extends AbstractMap implements Map, Cloneable, Serializable {}

1.4. Итератор с быстрым отказом

Iterator в HashMap является fail-fast и выдает ConcurrentModificationException, если любой другой поток изменяет структуру карты, добавляя или удаляя любой элемент, кроме собственного метода remove() Iterator. Но это не гарантированное поведение, и JVM будет делать это по мере сил. Перечислитель для Hashtable не является fail-fast.

HashMap<String, String> hashMap = new HashMap<String, String>();hashMap.put("key1", "value1");hashMap.put("key2", "value2");hashMap.put("key3", "value3");hashMap.put("key4", "value4");Iterator<String> iterator = hashMap.keySet().iterator();while(iterator.hasNext()){iterator.next();iterator.remove();System.out.println(hashMap);}Output:{key3=value3, key2=value2, key1=value1}{key2=value2, key1=value1}{key1=value1}{}

1.5.метод contains()

Наконец, Map исправляет небольшой недостаток в интерфейсе Hashtable. Hashtable имеет метод под названием « contains() »(наряду с «containsValue()» и «containsKey()»), который возвращает true, если Hashtable содержит заданное значение. Учитывая его название, можно ожидать, что этот метод вернет true, если Hashtable содержит заданный ключ, поскольку ключ является основным механизмом доступа для Hashtable.

Интерфейс Map устраняет этот источник путаницы, удаляя этот метод и оставляя только «containsValue()» и «containsKey()».

public boolean containsKey(Object obj) {...}public boolean containsValue(Object obj) {...}

2. Когда использовать HashMap и Hashtable

Вряд ли найдется работа, которую HashMap или связанные с ним классы(например, LinkedHashMap или ConcurrentHashMap) не могут сделать, а HashTable делает. Поэтому нет никаких веских причин использовать Hashtable в новом коде, который вы пишете. Всегда предпочитайте использовать HashMap вместо HashTable.

Действительно сложно углубляться в этот список. Как только вы сможете понять вышеуказанные различия, вы сможете использовать оба класса(на самом деле, вам следует использовать только HashMap). Для меня анализ за пределами вышеуказанных пунктов — просто пустая трата времени. Поэтому я останавливаюсь здесь.

Прокрутить вверх