Вопрос: Различия между HashMap и Hashtable?


Каковы различия между HashMapи Hashtableв Java?

Что более эффективно для не-резьбовых приложений?


3067


источник


Ответы:


Существует несколько различий между HashMapа также Hashtableв Java:

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

  2. Hashtableне позволяет nullключей или значений. HashMapпозволяет nullключ и любое количество nullзначения.

  3. Одним из подклассов HashMap является LinkedHashMap, поэтому в случае, если вам нужен предсказуемый порядок итерации (который по умолчанию является порядком размещения), вы можете легко заменить HashMapдля LinkedHashMap, Это было бы не так просто, если бы вы использовали Hashtable,

Поскольку синхронизация не является проблемой для вас, я бы рекомендовал HashMap, Если синхронизация становится проблемой, вы также можете посмотреть ConcurrentHashMap,


3164



Обратите внимание, что в большинстве ответов указано, что Hashtable синхронизирован. На практике это покупает вас очень мало. Синхронизация в методах accessor / mutator остановит два потока, добавляя или удаляя с карты одновременно, но в реальном мире вам часто потребуется дополнительная синхронизация.

Очень распространенная идиома заключается в том, чтобы «проверить, затем поставить», то есть искать запись на карте и добавить ее, если она еще не существует. Это никоим образом не атомная операция, если вы используете Hashtable или HashMap.

Эквивалентно синхронизированный HashMap можно получить:

Collections.synchronizedMap(myMap);

Но для правильной реализации этой логики вам нужно дополнительная синхронизация формы:

synchronized(myMap) {
    if (!myMap.containsKey("tomato"))
        myMap.put("tomato", "red");
}

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

Реализации ConcurrentMap интерфейс (например ConcurrentHashMap ) решить часть этого, включив потоковая безопасная семантика check-then-act такие как:

ConcurrentMap.putIfAbsent(key, value);

575



Никто не упомянул тот факт, что Hashtableявляется не часть Java Collections Framework - он просто предоставляет аналогичный API. Также, Hashtableсчитается устаревшим кодом. Нет ничего о Hashtableэто невозможно сделать, используя HashMapили производные HashMap, поэтому для нового кода я не вижу никаких оправданий для возврата к Hashtable,


287



Этот вопрос часто задают в интервью, чтобы проверить, понимает ли кандидат правильное использование классов сбора и знает альтернативные решения.

  1. Класс HashMap примерно эквивалентен Hashtable, за исключением того, что он не синхронизирован и разрешает null. (HashMap допускает нулевые значения как ключ и значение, тогда как Hashtable не допускает значения NULL).
  2. HashMap не гарантирует, что порядок карты останется постоянным с течением времени.
  3. HashMap не синхронизируется, тогда как Hashtable синхронизируется.
  4. Итератор в HashMap является отказоустойчивым, в то время как перечислитель для Hashtable не является и бросает ConcurrentModificationException, если какой-либо другой поток модифицирует структуру структурно, добавляя или удаляя любой элемент, кроме собственного метода remove () Iterator. Но это не гарантированное поведение и будет сделано JVM с наилучшими усилиями.

Примечание о некоторых важных условиях

  1. Синхронизированный означает, что только один поток может изменить хеш-таблицу в один момент времени. В принципе, это означает, что любой поток перед выполнением обновления на хэш-таблице должен будет получить блокировку объекта, в то время как другие будут ждать выхода блокировки.
  2. Отказоустойчивость относится к контексту итераторов. Если итератор был создан в объекте коллекции, а какой-либо другой поток пытается изменить объект коллекции «структурно», будет выбрано исключение параллельной модификации. Для других потоков можно использовать хотя бы вызов метода «set», так как он не модифицирует коллекцию «структурно». Однако, если до вызова «set» коллекция была изменена структурно, будет выбрано «IllegalArgumentException».
  3. Структурная модификация означает удаление или вставку элемента, который мог бы эффективно изменить структуру карты.

HashMap можно синхронизировать по

Map m = Collections.synchronizeMap(hashMap);

Карта предоставляет представления коллекции вместо прямой поддержки итерации  через объекты Enumeration. Взгляды коллекции значительно улучшают  выразительность интерфейса, как обсуждается далее в этом разделе.  Карта позволяет выполнять итерацию по ключам, значениям или парам ключ-значение;  Hashtable не предоставляет третий вариант. Карта обеспечивает безопасный способ  для удаления записей в середине итерации; Hashtable этого не делал.  Наконец, Map исправляет незначительный недостаток в интерфейсе Hashtable.  Hashtable имеет метод, называемый contains, который возвращает true, если  Hashtable содержит заданное значение. Учитывая его название, вы ожидаете этого  метод для возврата true, если Hashtable содержал данный ключ, потому что  ключ является основным механизмом доступа для Hashtable. Карта  интерфейс устраняет этот источник путаницы, переименовывая метод  containsValue. Кроме того, это улучшает согласованность интерфейса -  containsValue parallels содержитKey.

Интерфейс карты


148



Имейте в виду, что HashTableбыл унаследованным классом до внедрения Java Collections Framework (JCF) и позднее был модернизирован для реализации Mapинтерфейс. Так было Vectorа также Stack,

Поэтому всегда держитесь подальше от них в новом коде, поскольку в JCF всегда есть лучшая альтернатива как указывали другие.

Здесь Сборник чит-карт Java что вы найдете полезным. Обратите внимание, что серый блок содержит устаревший класс HashTable, Vector и Stack.

enter image description here


104



HashMap: An implementation of the Map interface that uses hash codes to index an array. Hashtable: Hi, 1998 called. They want their collections API back.

Seriously though, you're better off staying away from Hashtable altogether. For single-threaded apps, you don't need the extra overhead of synchronisation. For highly concurrent apps, the paranoid synchronisation might lead to starvation, deadlocks, or unnecessary garbage collection pauses. Like Tim Howland pointed out, you might use ConcurrentHashMap instead.


104



In addition to what izb said, HashMap allows null values, whereas the Hashtable does not.

Also note that Hashtable extends the Dictionary class, which as the Javadocs state, is obsolete and has been replaced by the Map interface.


58



Take a look at this chart. It provides comparisons between different data structures along with HashMap and Hashtable. The comparison is precise, clear and easy to understand.

Java Collection Matrix


50