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

3217

В чем разница между HashMap и Hashtable в Java?

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

  • 9
    HashTable устарел в Java 1.7, и рекомендуется использовать реализацию ConcurrentMap
Теги:
collections
hashmap
hashtable

39 ответов

3133
Лучший ответ

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

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

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

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

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

  • 59
    Если вы хотите сделать HashMap потокобезопасным, используйте Collections.synchronizedMap() .
  • 228
    Я также хотел бы прокомментировать, что наивный подход к безопасности потоков в Hashtable («синхронизация каждого метода должен решать любые проблемы с параллелизмом!») Значительно ухудшает работу многопоточных приложений. Вам лучше синхронизировать внешнюю HashMap (и думать о последствиях), либо использовать реализацию ConcurrentMap (и использовать ее расширенный API для параллелизма). Итог: единственная причина использовать Hashtable - это когда устаревший API (примерно с 1996 года) требует этого.
Показать ещё 4 комментария
569

Обратите внимание, что в большинстве ответов указано, что 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);
  • 47
    Также обратите внимание, что при изменении HashMap итераторы, указывающие на него, становятся недействительными.
  • 19
    Итератор сгенерирует ConcurrentModificationException, верно?
Показать ещё 4 комментария
317

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

  • 93
    От Hashtable javadoc (выделение добавлено): «Начиная с платформы Java 2 v1.2, этот класс был модифицирован для реализации интерфейса Map, что сделало его членом Java Collections Framework ». Тем не менее, вы правы, что это устаревший код. Все преимущества синхронизации можно получить более эффективно с Collections.synchronizedMap (HashMap). (Подобно тому, как Vector является устаревшей версией Collections.synchronizedList (ArrayList).)
  • 15
    @ aberrant80: к сожалению, у вас нет выбора между ними, и вы должны использовать Hashtable при программировании для J2ME ...
Показать ещё 3 комментария
161

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

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

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

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

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

Map m = Collections.synchronizeMap(hashMap);

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

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

  • 18
    Этот ответ содержит как минимум 2 существенные фактические неточности. Это, конечно, не заслуживает этого много голосов.
  • 55
    1) Итераторы HashMap НЕ являются отказоустойчивыми. Они быстро проваливаются. Существует огромная разница в значении между этими двумя терминами. 2) В HashMap нет set операции. 3) Операция put(...) не вызовет IllegalArgumentException если произошли предыдущие изменения. 4) Отказоустойчивое поведение HashMap также происходит, если вы измените отображение. 5) Нерабочий-быстро поведение гарантировано. (Что не гарантируется, так это поведение HashTable если вы делаете параллельную модификацию. Фактическое поведение ... непредсказуемо.)
Показать ещё 3 комментария
108

HashMap: реализация интерфейса Map, который использует хэш-коды для индексации массива. Hashtable: Привет, 1998. Они хотят вернуть API их коллекций.

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

  • 0
    Это на самом деле имеет смысл. ConcurrentHashMaps дает вам свободу синхронизации, а отладка намного проще.
  • 1
    Это специфично для Java или для всех реализаций хеш-карты.
102

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

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

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

Изображение 1301

57

В дополнение к тому, что сказал izb, HashMap допускает нулевые значения, тогда как Hashtable не работает.

Также обратите внимание, что Hashtable расширяет класс Dictionary, который как состояние Javadocs устарел и был заменен на Map.

  • 3
    но это не делает HashTable устаревшим, не так ли?
51

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

Матрица Java Collection

  • 0
    спасибо, теперь я знаю, что выбрать в моем сценарии.
42

Hashtable похож на HashMap и имеет аналогичный интерфейс. Рекомендуется использовать HashMap, если вам не нужна поддержка устаревших приложений или вам нужна синхронизация, поскольку методы Hashtables синхронизированы. Таким образом, в вашем случае, поскольку вы не многопоточны, HashMaps - ваш лучший выбор.

37

Существует много хорошего ответа, уже опубликованного. Я добавляю несколько новых пунктов и суммирую их.

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

HashMap

  1. HashMap не синхронизирован. Он не является потокобезопасным и не может быть разделен между многими потоками без надлежащего кода синхронизации.
  2. HashMap позволяет использовать один нулевой ключ и несколько нулевых значений.
  3. HashMap - новый класс, представленный в JDK 1.2.
  4. HashMap работает быстро.
  5. Мы можем сделать HashMap синхронизированным, вызвав этот код
    Map m = Collections.synchronizedMap(HashMap);
  6. HashMap проходит через Iterator.
  7. Итератор в HashMap работает не быстро.
  8. HashMap наследует класс AbstractMap.

Хеш-таблица

  1. Синхронизируется Hashtable. Он потокобезопасен и может использоваться совместно со многими потоками.
  2. Hashtable не допускает никакого нулевого ключа или значения.
  3. Hashtable - это унаследованный класс.
  4. Hashtable медленный.
  5. Hashtable внутренне синхронизирован и не может быть несинхронизирован.
  6. Hashtable проходит через Enumerator и Iterator.
  7. Перечислитель в Hashtable не работает быстро.
  8. Hashtable наследует класс словаря.

Дальнейшее чтение. Какая разница между HashMap и Hashtable в Java?

Изображение 1302

  • 0
    В значительной степени рассматривается в этом ответе (дубликат) - stackoverflow.com/a/39785829/432903 .
  • 0
    Почему вы говорите ~ " Hashtable - это класс наследства "? Где находится подтверждающая документация для этого.
Показать ещё 2 комментария
30

Другое ключевое различие между hashtable и hashmap заключается в том, что Iterator в HashMap работает с ошибкой, в то время как перечислитель для Hashtable не является и бросает ConcurrentModificationException, если какой-либо другой поток модифицирует структуру структурно, добавляя или удаляя любой элемент, кроме собственного Итератора remove (). Но это не гарантированное поведение и будет выполняться JVM с наилучшими усилиями ".

Мой источник: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html

28

Помимо всех других важных аспектов, уже упомянутых здесь, API коллекций (например, интерфейс карты) постоянно изменяется, чтобы соответствовать последним и самым большим дополнениям к спецификации Java.

Например, сравните Java 5 Map iterating:

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...: (

Могут ли улучшения коллекции Coin в JDK8?

25
  • HashTable синхронизируется, если вы используете его в одном потоке, вы можете использовать HashMap, который является несинхронизированной версией. Несинхронизированные объекты часто немного более эффективны. Кстати, если несколько потоков одновременно обращаются к HashMap, и по крайней мере один из потоков изменяет структуру структурно, он должен быть синхронизирован извне. Youn может обернуть несинхронизированную карту в синхронизированном режиме, используя:

    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 я предполагаю, что это одно и то же, но я не совсем уверен, я не нахожу ressource, который четко заявляет об этом.

23

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

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

23

Hashtable синхронизируется, а HashMap - нет. Это делает Hashtable медленнее, чем Hashmap.

Для приложений, не связанных с потоком, используйте HashMap, поскольку они в остальном одинаковы с точки зрения функциональности.

21

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

1) Thread Safe

  • HashTable внутренне синхронизирован.
  • Поэтому очень удобно использовать HashTable в многопоточных приложениях.
  • Где HashMap не синхронизирован внутренне.
  • Поэтому небезопасно использовать HashMap в многопоточных приложениях без внешней синхронизации.
  • Вы можете синхронизировать HashMap извне с помощью метода Collections.synchronizedMap().

2) Унаследовано от

  • Хотя оба интерфейса HashMap и HashTable реализуют интерфейс Map, но они расширяют два разных класса.
  • HashMap расширяет класс AbstractMap, где, поскольку HashTable расширяет класс Dictionary, который является унаследованным классом в java.

3) Нулевые ключи и нулевые значения

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

4) Обход

  • HashMap возвращает только Итераторы, которые используются для перемещения по элементам HashMap.
  • HashTable возвращает Iterator, а также Enumeration, который может использоваться для перемещения по элементам HashTable.

5) Fail-Fast Vs Fail-Safe

  • Итератор, возвращаемый HashMap, несовместим с природой, то есть они бросают ConcurrentModificationException, если HashMap изменен после создания Итератора, кроме итератора, собственный метод remove().
  • С другой стороны, перечисление, возвращаемое HashTable, является отказоустойчивым по своей природе, то есть они не выбрасывают никаких исключений, если HashTable изменяется после создания Enumeration.

6) Производительность

  • Поскольку HashTable внутренне синхронизирован, это делает HashTable немного медленнее, чем HashMap.

7) Класс Legacy

  • HashTable - это унаследованный класс.
  • Он считается почти неприемлемым.
  • Поскольку JDK 1.5, ConcurrentHashMap считается лучшим вариантом, чем HashTable.

8) Член Framework для Java

  • HashMap является членом Java Collection Framework с самого начала его внедрения в JDK 1.2.
  • Но HashTable был там до JDK 1.2. Из JDK 1.2 было сделано для реализации интерфейса Map, что делает его частью структуры коллекции.

Изображение 1303

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

  • Hashtable синхронизируется, а HashMap - нет.

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

19

Основываясь на информации здесь, я бы рекомендовал пойти с HashMap. Я думаю, что самым большим преимуществом является то, что Java не позволит вам изменить его, пока вы выполняете итерацию по нему, если вы не сделаете это через итератор.

  • 5
    На самом деле это не предотвращает, а просто обнаруживает и выдает ошибку.
  • 1
    Я почти уверен, что он выдаст исключение ConncurrentModificationException до изменения базовой коллекции, хотя я могу ошибаться.
Показать ещё 1 комментарий
15

Collection - иногда называемая контейнером - это просто объект, который группирует несколько элементов в один блок. Collection используется для хранения, извлечения, манипулирования и обмена совокупными данными. Рамка коллекций W представляет собой единую архитектуру для представления и управления коллекциями.

HashMap JDK1.2 и Hashtable JDK1.0 оба используются для представления группы объектов, представленных в паре <Key, Value>. Каждая пара <Key, Value> называется объектом Entry. Сбор записей относится к объекту HashMap и Hashtable. Ключи в коллекции должны быть уникальными или отличительными. [поскольку они используются для извлечения отображаемого значения определенного ключа. значения в коллекции могут быть дублированы.]


" Членство в суперклассе, наследие и сборник

Hashtable - это унаследованный класс, представленный в JDK1.0, который является подклассом класса Dictionary. Из JDK1.2 Hashtable повторно спроектирован для реализации интерфейса карты, чтобы стать членом структуры коллекции. 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).

Изображение 1304

" Структурная модификация в случае хеш-столкновения

HashMap, Hashtable в случае хеш-коллизий, они хранят записи в связанных списках. Из Java8 для HashMap если хэш-ведро растет выше определенного порога, этот ковш переключится с linked list of entries to a balanced tree. которые улучшают наихудшую производительность от O (n) до O (log n). При преобразовании списка в двоичное дерево hashcode используется как переменная ветвления. Если в одном ковше есть два разных хэш-кода, один считается большим и направляется справа от дерева, а другой - влево. Но когда оба хэш-кода равны, HashMap предполагает, что ключи сопоставимы, и сравнивает ключ, чтобы определить направление, чтобы можно было поддерживать некоторый порядок. Хорошая практика - сделать ключи от HashMap сопоставимыми. При добавлении записей, если размер ведра достигает TREEIFY_THRESHOLD = 8 конвертируйте связанный список записей в сбалансированное дерево, при удалении записей меньше TREEIFY_THRESHOLD и самое UNTREEIFY_THRESHOLD = 6 сбалансированное дерево в связанный список записей. Java 8 SRC, stackpost

" Инициация просмотра коллекции, Fail-Fast и Fail-Safe

    +--------------------+-----------+-------------+
    |                    | Iterator  | Enumeration |
    +--------------------+-----------+-------------+
    | Hashtable          | fail-fast |    safe     |
    +--------------------+-----------+-------------+
    | HashMap            | fail-fast | fail-fast   |
    +--------------------+-----------+-------------+
    | ConcurrentHashMap  |   safe    |   safe      |
    +--------------------+-----------+-------------+

Iterator является неустойчивым по своей природе. т.е. он выбрасывает ConcurrentModificationException, если коллекция изменяется при повторении, кроме собственного метода remove(). Где, как Enumeration является отказоустойчивым по своей природе. Он не бросает никаких исключений, если коллекция изменяется во время итерации.

Согласно Java API Docs, Iterator всегда предпочитается над Enumeration.

ПРИМЕЧАНИЕ. Функциональность интерфейса Enumeration дублируется интерфейсом Iterator.Кроме того, Iterator добавляет дополнительную операцию удаления и имеет более короткие имена методов.В новых реализациях следует рассмотреть возможность использования Iterator в предпочтении Enumeration.

В Java 5 представлен интерфейс ConcurrentMap: ConcurrentHashMap - высококонкурентная высокопроизводительная реализация ConcurrentMap поддерживаемая хэш-таблицей. Эта реализация никогда не блокируется при выполнении повторных попыток и позволяет клиенту выбирать уровень параллелизма для обновлений. Он предназначен для замены Hashtable: помимо реализации ConcurrentMap он поддерживает все "унаследованные" методы, свойственные Hashtable.

  • Каждое значение HashMapEntry является летучим, обеспечивая тем самым HashMapEntry согласованность зерен для согласованных модификаций и последующих чтений; каждое чтение отражает последнее завершенное обновление

  • Итераторы и перечисления являются безопасными - отражая состояние в какой-то момент с момента создания итератора/перечисления; это позволяет одновременно считывать и изменять за счет уменьшения согласованности. Они не выбрасывают 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 использовать Hashtable в многопоточных приложениях. Если HashMap не синхронизирован внутри страны. Поэтому небезопасно использовать HashMap в многопоточных приложениях без внешней синхронизации. Вы можете синхронизировать HashMap извне с помощью метода Collections.synchronizedMap().

" Производительность

Поскольку Hashtable внутренне синхронизирован, это делает Hashtable немного медленнее, чем HashMap.


@Видеть

15

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

13

Помимо упомянутых различий, следует отметить, что, поскольку Java 8, HashMap динамически заменяет Узлы (связанный список), используемые в каждом ведре с TreeNodes (красно-черным деревом), так что даже если высокие хэш-коллизии существуют, худший случай при поиске -

O (log (n)) для HashMap Vs O (n) в Hashtable.

* Вышеупомянутое улучшение еще не применялось к Hashtable, но только к HashMap, LinkedHashMap и ConcurrentHashMap.

FYI, в настоящее время

  • TREEIFY_THRESHOLD = 8: если ведро содержит более 8 узлов, связанный список преобразуется в сбалансированное дерево.
  • UNTREEIFY_THRESHOLD = 6: когда ведро становится слишком маленьким (из-за удаления или изменения размера) дерево преобразуется обратно в связанный список.
12

Разница между HashMap и HashTable/HashMap vs HashTable

  • Синхронизация или потоковая безопасность: это самое важное различие между двумя. HashMap не синхронизирован, а не потокобезопасен. С другой стороны, HashTable является потокобезопасным и синхронизированным. Когда использовать HashMap? Ответ: если ваше приложение не требует многопоточной задачи, другими словами hashmap лучше для приложений без потоковой передачи. HashTable следует использовать в многопоточных приложениях.

  • Нулевые ключи и нулевые значения: Hashmap позволяет использовать один нулевой ключ и любое количество нулевых значений, в то время как Hashtable не допускает нулевые ключи и значения null в объекте HashTable.

  • Итерирование значений: значения объекта Hashmap повторяются с помощью итератора .HashTable - это единственный класс, отличный от вектора, который использует перечислитель для итерации значений объекта HashTable.

  • Неудачный итератор: итератор в Hashmap является отказоустойчивым итератором, а перечислитель для Hashtable - нет. Согласно Oracle Docs, если Hashtable структурно модифицируется в любое время после создания итератора любым способом, кроме метода удаления iterator, то итератор будет вызывать ConcurrentModification Exception. Структурная модификация означает добавление или удаление элементов из объекта Collection (здесь hashmap или hashtable). Таким образом, перечисления, возвращаемые ключами и элементами Hashtable, не ускоряются быстро. Мы уже объяснили разницу между итератором и перечислением.

  • Производительность: Hashmap работает намного быстрее и использует меньше памяти, чем Hashtable, поскольку прежняя несинхронизирована. Несинхронизированные объекты часто намного лучше в производительности по сравнению с синхронизированным объектом, например Hashtable, в однопоточной среде.

  • Суперкласс и наследие: Hashtable является подклассом класса Dictionary, который теперь устарел в Jdk 1.7, поэтому он больше не используется. Лучше синхронизировать внешнюю синхронизацию HashMap или использовать реализацию ConcurrentMap (например, ConcurrentHashMap).HashMap является подклассом класса AbstractMap. Хотя Hashtable и HashMap имеют разные суперклассы, но оба они являются реализациями абстрактных типов данных "Карта".

12

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);
  • 1
    4-ый дифференциал хорош, никто не упомянул это, спасибо
10

Мой небольшой вклад:

  • Первым и самым значительным отличием между Hashtable и HashMap является то, что HashMap не является потокобезопасным, а Hashtable является поточно-безопасной коллекцией.

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

  • Третья разница в Hashtable vs HashMap заключается в том, что Hashtable является устаревшим классом, и вы должны использовать ConcurrentHashMap вместо Hashtable в Java.

10

Существует 5 основных различий с HashTable и HashMaps.

  • Карты позволяют выполнять итерацию и извлечение ключей, значений и обеих пар ключ-значение, где HashTable не обладает всей этой возможностью.
  • В Hashtable есть функция contains(), которая очень запутанна в использовании. Потому что смысл содержания немного отклоняется. Значит ли это, содержит ключ или содержит значение? трудно понять. То же самое в Maps имеет функции ContainsKey() и ContainsValue(), которые очень легко понять.
  • В hashmap вы можете удалить элемент во время итерации, безопасно. где это невозможно в хэш-таблицах.
  • Хэш-таблицы по умолчанию синхронизированы, поэтому их можно легко использовать с несколькими потоками. Где по умолчанию HashMaps не синхронизируется, поэтому их можно использовать только с одним потоком. Но вы можете преобразовать HashMap в синхронизированный с помощью функции Collections util class synchronizedMap (Map m).
  • HashTable не разрешает нулевые ключи или нулевые значения. Где, поскольку HashMap допускает один нулевой ключ и несколько нулевых значений.
8

HashTable является устаревшим классом в jdk, который больше не должен использоваться. Замените его использование ConcurrentHashMap. Если вы не нуждаетесь в безопасности потоков, используйте HashMap, который не является threadsafe, но быстрее и использует меньше памяти.

  • 0
    Почему вы повторяете уже полученный ответ?
  • 0
    Потому что я думал, что другие ответы в то время не отклоняли HashTable, но объяснили, что это потокобезопасно. Правда в том, что как только вы увидите HashTable в коде, вы должны заменить его на ConcurrentHashMap, не пропуская удар. И если безопасность потоков не является проблемой, HashMap может быть использован для повышения производительности.
7

1) Hashtable синхронизируется, а hashmap - нет. 2) Еще одно отличие заключается в том, что итератор в HashMap является отказоустойчивым, а перечислитель для Hashtable - нет. Если вы измените карту во время итерации, вы узнаете.

3) HashMap разрешает в нем нулевые значения, а Hashtable - нет.

  • 3
    Итератор HashMap является отказоустойчивым и небезопасным. Вот почему у нас есть ConcurrentHashMap, который позволяет модификацию во время итерации. Проверьте это сообщение journaldev.com/122/…
  • 3
    Почему вы повторяете уже полученный ответ?
6

HashMap: - Это класс, доступный внутри пакета java.util, и он используется для хранения элемента в формате ключа и значения.

Hashtable: -Это унаследованный класс, который распознается внутри рамки коллекции

  • 4
    Почему вы повторяете уже полученный ответ?
5

Hashtable:

Hashtable - это структура данных, которая сохраняет значения пары ключ-значение. Он не разрешает null для обоих ключей и значений. Вы получите 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, но также принимает пару значений ключа. Он позволяет использовать null для обоих ключей и значений. Его производительность лучше, чем 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));

    }
}
5

HashMap и HashTable

  • Некоторые важные моменты в HashMap и HashTable.  пожалуйста, прочтите ниже подробные сведения.

1) Hashtable и Hashmap реализуют интерфейс java.util.Map 2) Hashmap и Hashtable - это коллекция, основанная на хеше. и работает над хэшированием. поэтому это сходство HashMap и HashTable.

  • В чем разница между HashMap и HashTable?

1) Первое отличие заключается в том, что HashMap не является потокобезопасным, а HashTable - ThreadSafe
2) HashMap работает лучше, потому что он не является потокобезопасным. в то время как производительность Hashtable мудрая не лучше, потому что это потокобезопасная. поэтому несколько потоков не могут одновременно обращаться к Hashtable.

  • 1
    Проголосовали, потому что этот ответ не является правильным в некоторых аспектах. Hashtable не реализует интерфейс Map, а только расширяет класс Dictionary, который устарел.
4

Синхронизация или безопасность потоков:

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

Нулевые ключи и нулевые значения:

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

Итерирование значений:

Итератор в HashMap является отказоустойчивым итератором, в то время как перечислитель для Hashtable не является и бросает ConcurrentModificationException, если какой-либо другой поток модифицирует структуру структурно, добавляя или удаляя любой элемент, кроме собственного метода remove() Iterators.

Суперкласс и наследие:

HashMap является подклассом класса AbstractMap, тогда как Hashtable является подклассом класса Dictionary.

Производительность:

Поскольку HashMap не синхронизирован, он быстрее по сравнению с Hashtable.

Обратитесь http://modernpathshala.com/Article/1020/difference-between-hashmap-and-hashtable-in-java к примерам и опросите вопросы и опрос, связанные с сборкой Java

4

HashMap эмулируется и поэтому может использоваться в GWT client code, тогда как Hashtable не является.

  • 0
    Это полное описание различий между двумя API?
  • 0
    Да (так!). Это все, что разработчики GWT должны знать об этом.
4

HashMaps дает вам свободу синхронизации и отладки намного проще

  • 2
    Почему вы повторяете уже полученный ответ?
  • 2
    Что означает « свобода синхронизации »?
3

HashMap - это класс, используемый для хранения элемента в ключе и формате format.it не является потокобезопасным. потому что он не синхронизирован. В том случае, когда Hashtable синхронизируется. Hashmap разрешает null, но hastable не разрешает null.

  • 2
    Почему вы повторяете уже полученный ответ?
2

Старая и классическая тема, просто хочу добавить этот полезный блог, который объясняет это:

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 был модернизирован для реализации интерфейса карты, что делает его членом Рамки коллекций Java.

  • Одно из основных различий между HashMap и Hashtable заключается в том, что HashMap не синхронизирован, тогда как Hashtable синхронизируется, что означает, что Hashtable является потокобезопасным и может использоваться совместно несколькими потоки, но HashMap нельзя разделить между несколькими потоками без правильная синхронизация. Java 5 представила ConcurrentHashMap, которая альтернатива Hashtable и обеспечивает лучшую масштабируемость, чем Hashtable в Java.Synchronized означает, что только один поток может изменять хэш таблицу в один момент времени. В основном это означает, что любой поток до выполнение обновления на хэш-таблице должно будет получить блокировку на объект, в то время как другие будут ждать освобождения блокировки.

  • Класс HashMap примерно эквивалентен Hashtable, за исключением того, что он допускает null. (HashMap допускает нулевые значения как ключ и значение, тогда как Hashtable не разрешает null).

  • Третье существенное различие между HashMap и Hashtable заключается в том, что Iterator в HashMap является отказоустойчивым итератором, а перечислитель для Hashtable отсутствует и бросается ConcurrentModificationException, если какой-либо другой Thread изменяет карту структурно, добавляя или удаляя любой элемент, за исключением самих итераторов remove(). Но это не гарантированное поведение и будет сделанные JVM с наилучшими усилиями. Это также важное различие между Enumeration и Iterator в Java.

  • Еще одна заметная разница между Hashtable и HashMap заключается в том, что из-за безопасности потоков и синхронизации Hashtable намного медленнее чем HashMap, если используется в среде с одним потоком. Так что если вы не нужна синхронизация, а HashMap используется только одним потоком, это выполнить Hashtable в Java.

  • HashMap не гарантирует, что порядок карты останется постоянным с течением времени.

Обратите внимание, что HashMap можно синхронизировать с помощью

Map m = Collections.synchronizedMap(hashMap);

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

  • 0
    ConcurrentHashMap не синхронизируется по чтению, тогда как Hashtable есть. Таким образом, если у вас большое количество операций чтения, происходящих одновременно с записью, Hashtable будет лучше служить вам, если вы заботитесь о целостности данных.
2

Так как Hashtable в Java является подклассом класса Dictionary, который теперь устарел из-за существования интерфейса карты, он больше не используется. Более того, вы не можете ничего сделать с классом, который реализует интерфейс карты, который вы можете сделать с помощью Hashtable.

  • 0
    Почему вы повторяете уже полученный ответ?
1

HashTable устарел в Java 1.7, и рекомендуется использовать реализацию ConcurrentMap

1

1.HashMap не синхронизируется, тогда как Hashtable синхронизируется.

2.HashMap не гарантирует, что порядок карты останется постоянным с течением времени.

3. Еще одна заметная разница между Hashtable и HashMap заключается в том, что из-за безопасности потоков и синхронизации Hashtable намного медленнее, чем HashMap, если используется в среде с одним потоком.

0

Ниже приведены некоторые различия между Hashmap и Hashtable:

Примечание. Hashtable был obselete в Java 1.7, и рекомендуется использовать ConcurrentMap.

Синхронизация или поточный сейф: это самая существенная разница между двумя. HashMap не синхронизирован, а не потокобезопасен. С другой стороны, Hashtable является потокобезопасным и синхронизированным. Когда использовать HashMap? ответ заключается в том, что ваше приложение не требует многопоточной задачи, другими словами, HashMap лучше подходит для приложений без потоковой передачи. Hashtable следует использовать в многопоточных приложениях

Нулевые ключи и нулевые значения: HashMap допускает один нулевой ключ и любое количество нулевых значений, в то время как Hashtadoese не разрешает нулевые ключи и нулевые значения в объекте Hashtable.

Итерирование значений: значения объекта HashMap повторяются с помощью итератора. Hashtable - единственный класс, отличный от вектора, который использует перечислитель для итерации значений объекта Hashtable.

Истребитель с быстрым хостом: итератор в HashMap - это быстрый итератор, в то время как перечислитель для Hashtable - нет. Согласно Oracle Docs, если Hashtable структурно модифицируется в любое время после создания итератора каким-либо образом, кроме метода удаления итератора, то итератор будет вызывать ConcurrentModification Exception. Структурная модификация означает добавление или удаление элементов из объекта Collection (здесь HashMap или Hashtable). Таким образом, перечисления, возвращаемые ключами и элементами Hashtable, не ускоряются быстро. Мы уже объяснили разницу между итератором и перечислением.

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

Superclass и Legacy: Hashtable - это подкласс класса Dictionary, который теперь устарел в JDK 1.7, поэтому он больше не используется. Лучше синхронизировать HashMap извне или использовать реализацию ConcurrentMap (например, ConcurrentHashMap).HashMap является подклассом класса AbstractMap. Хотя Hashtable и HashMap имеют разные суперклассы, они оба являются реализациями абстрактного типа данных "Карта".

0

Класс Hashtable синхронизирован, то есть он предназначен для использования приложениями, которые обрабатывают многопоточный или многопоточный процесс. Синхронизированные классы менее эффективны в классическом случае приложения для процесса, поэтому класс Hashmap быстрее вообще. Класс HashTable не принимает значение Null, как для ключей, так и для значений, в то время как класс HashMap позволяет использовать один ключ с нулевым и максимально допустимым значением.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню