В чем разница между HashMap
и Hashtable
в Java?
Что более эффективно для непоточных приложений?
30 ответов
Между 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
считается устаревшим кодом. В Hashtable
нет ничего, что нельзя было бы сделать с помощью HashMap
или производных от HashMap
, поэтому для нового кода я не вижу никаких оснований для возврата к Hashtable
.
Этот вопрос часто задают на собеседовании, чтобы проверить, понимает ли кандидат правильное использование классов коллекции и знает ли он об имеющихся альтернативных решениях.
- Класс
HashMap
примерно эквивалентенHashtable
, за исключением того, что он не синхронизирован и допускает значения NULL. (HashMap
допускает нулевые значения как ключ и значение, тогда какHashtable
не допускаетnull
s). HashMap
не гарантирует, что порядок карты останется постоянным с течением времени.HashMap
не синхронизируется, тогда какHashtable
синхронизируется.- Итератор в
HashMap
является отказоустойчивым, в то время как перечислитель дляHashtable
- нет, и выдаетConcurrentModificationException
, если какой-либо другой поток структурно изменяет карту, добавляя или удаляя любой элемент, кромеIterator
собственный методremove()
. Но это не гарантированное поведение, и JVM сделает все возможное.
Обратите внимание на некоторые важные термины:
- Синхронизированный означает, что только один поток может изменять хеш-таблицу в один момент времени. По сути, это означает, что любой поток перед выполнением обновления
Hashtable
должен будет получить блокировку объекта, в то время как другие будут ждать снятия блокировки. - Отказоустойчивость важна в контексте итераторов. Если итератор был создан для объекта коллекции, и какой-то другой поток пытается изменить объект коллекции «структурно», будет сгенерировано исключение одновременной модификации. Однако другие потоки могут вызвать метод
set
, поскольку он не изменяет коллекцию «структурно». Однако, если до вызоваset
коллекция была структурно изменена, будет выброшеноIllegalArgumentException
. - Структурная модификация означает удаление или вставку элемента, который может эффективно изменить структуру карты.
HashMap
можно синхронизировать с помощью
Map m = Collections.synchronizeMap(hashMap);
Карта предоставляет представления коллекций вместо прямой поддержки итерации через объекты перечисления. Представления коллекций значительно улучшают выразительность интерфейса, как обсуждается далее в этом разделе. Карта позволяет вам перебирать ключи, значения или пары ключ-значение; Hashtable
не предоставляет третий вариант. Карта обеспечивает безопасный способ удаления записей во время итерации; Hashtable
- нет. Наконец, Map исправляет незначительный недостаток в интерфейсе Hashtable
. Hashtable
имеет метод contains, который возвращает истину, если Hashtable
содержит заданное значение. Учитывая его имя, можно ожидать, что этот метод вернет истину, если Hashtable
содержит данный ключ, потому что ключ является основным механизмом доступа для Hashtable
. Интерфейс карты устраняет этот источник путаницы, переименовав метод containsValue
. Кроме того, это улучшает согласованность интерфейса - containsValue
параллелей containsKey
.
set
с 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
проходит Iterator.- Итератор в
HashMap
работает без сбоев. HashMap
наследует класс AbstractMap.
Хеш-таблица
Hashtable
синхронизируется. Он потокобезопасен и может использоваться многими потоками.Hashtable
не допускает нулевого ключа или значения.Hashtable
- это устаревший класс.Hashtable
работает медленно.Hashtable
внутренне синхронизирован и не может быть рассинхронизирован.Hashtable
проходит Enumerator и Iterator.- Перечислитель в
Hashtable
не работает без сбоев. Hashtable
наследует класс Dictionary.
Дополнительная литература В чем разница между HashMap и Hashtable в Java?
Взгляните на эту диаграмму. Он обеспечивает сравнение между различными структурами данных вместе с HashMap
и Hashtable
. Сравнение точное, ясное и легкое для понимания.
В дополнение к тому, что сказано в izb, HashMap
допускает нулевые значения, а Hashtable
- нет.
Также обратите внимание, что Hashtable
расширяет класс Dictionary
, который как Javadocs устарело и было заменено интерфейсом Map
.
Hashtable
похож на HashMap
и имеет аналогичный интерфейс. Рекомендуется использовать HashMap
, если вам не требуется поддержка устаревших приложений или вам нужна синхронизация, поскольку методы Hashtables
синхронизируются. Так что в вашем случае, поскольку вы не используете многопоточность, HashMaps
- ваш лучший выбор.
Еще одно ключевое различие между хэш-таблицей и хэш-картой заключается в том, что Iterator в HashMap работает без сбоев, а перечислитель для Hashtable - нет, и генерирует исключение ConcurrentModificationException, если какой-либо другой поток структурно изменяет карту, добавляя или удаляя любой элемент, кроме собственного метода remove () Iterator. Но это не гарантированное поведение, и JVM сделает все возможное ".
Мой источник: http://javarevisited.blogspot.com/2010/ 10 / разница-между-hashmap-and.html
HashMap
и Hashtable
также имеют значительные алгоритмические различия. Никто не упоминал об этом раньше, поэтому я поднимаю этот вопрос. HashMap
создаст хеш-таблицу с размером степени два, динамически увеличит ее так, чтобы у вас было не более восьми элементов (коллизий) в любом сегменте, и будет очень хорошо перемешивать элементы для общих типов элементов. Однако реализация Hashtable
обеспечивает лучший и более точный контроль над хешированием, если вы знаете, что делаете, а именно, вы можете исправить размер таблицы, используя, например, ближайшее простое число к размеру вашего домена значений, и это приведет к лучшей производительности, чем HashMap, то есть к меньшему количеству коллизий в некоторых случаях.
Помимо очевидных различий, широко обсуждаемых в этом вопросе, я рассматриваю Hashtable как машину с «ручным приводом», где у вас есть лучший контроль над хешированием, а HashMap - как аналог «автоматического привода», который обычно хорошо работает.
Основываясь на информации, здесь, я бы рекомендовал использовать HashMap. Я думаю, что самым большим преимуществом является то, что Java не позволит вам изменить его во время итерации, если вы не сделаете это через итератор.
Для многопоточных приложений часто можно обойтись 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
: когда корзина становится слишком маленькой (из-за удаления или изменения размера), дерево преобразуется обратно в связанный список.
У HashTable и HashMaps есть 5 основных отличий.
- Карты позволяют вам перебирать и извлекать ключи, значения и обе пары ключ-значение, а у HashTable нет всех этих возможностей.
- В Hashtable есть функция contains (), которую очень сложно использовать. Потому что значение содержит несколько отклонений. Значит ли это содержит ключ или содержит значение? сложно понять. То же самое и в Maps, у нас есть функции ContainsKey () и ContainsValue (), которые очень легко понять.
- В hashmap вы можете безопасно удалить элемент во время итерации. где это невозможно в хэш-таблицах.
- Хэш-таблицы по умолчанию синхронизированы, поэтому их можно легко использовать с несколькими потоками. Где, поскольку HashMaps не синхронизируются по умолчанию, поэтому могут использоваться только с одним потоком. Но вы все равно можете преобразовать HashMap в синхронизированный с помощью функции synchronizedMap (Map m) класса утилит Collections.
- HashTable не допускает пустых ключей или нулевых значений. Где, поскольку HashMap допускает один нулевой ключ и несколько нулевых значений.
Мой небольшой вклад:
Первое и наиболее существенное различие между
Hashtable
иHashMap
заключается в том, чтоHashMap
не является поточно-ориентированной коллекцией, аHashtable
- поточно-ориентированной коллекцией. / p>Второе важное различие между
Hashtable
иHashMap
- это производительность, посколькуHashMap
не синхронизируется, он работает лучше, чемHashtable
.Третье отличие
Hashtable
отHashMap
заключается в том, чтоHashtable
является устаревшим классом, и вам следует использоватьConcurrentHashMap
вместоHashtable
в Java. .
HashMap: это класс, доступный внутри пакета java.util, который используется для хранения элемента в формате ключа и значения.
Hashtable: это устаревший класс, который распознается в рамках коллекции.
Hashtable
синхронизируется, аHashMap
- нет.- Другое отличие состоит в том, что итератор в
HashMap
отказоустойчив. в то время как перечислитель дляHashtable
- нет. Если вы измените карту во время итерации вы узнаете. HashMap
допускает в нем нулевые значения, аHashtable
- нет.
HashTable - это устаревший класс в jdk, который не следует больше использовать. Замените его использование ConcurrentHashMap . Если вам не требуется безопасность потоков, используйте HashMap a>, который не потокобезопасен но быстрее и использует меньше памяти.
HashMap и Hashtable используются для хранения данных в форме ключа и значения. Оба используют технику хеширования для хранения уникальных ключей. но есть много различий между классами HashMap и 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 , но также принимает пару "ключ-значение". Он допускает значение 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));
}
}
Старая и классическая тема, просто хочу добавить этот полезный блог, который объясняет это:
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.Synchronized означает, что только один поток может изменять хеш таблица в один момент времени. По сути, это означает, что любой поток до при обновлении хеш-таблицы необходимо заблокировать объект, в то время как другие будут ждать снятия блокировки.
Класс HashMap примерно эквивалентен Hashtable, за исключением того, что он допускает значения NULL. (HashMap допускает нулевые значения как ключ и значение, тогда как Hashtable не допускает значений NULL).
Третье существенное различие между HashMap и Hashtable состоит в том, что Iterator в HashMap является итератором, работающим без сбоев, в то время как перечислитель для Hashtable нет и бросить ConcurrentModificationException, если какой-либо другой поток изменяет карту структурно путем добавления или удаления любого элемента, кроме собственного Iterator 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.
Синхронизация или многопоточность:
Hash Map не синхронизирована, следовательно, она не является потокобезопасной и не может быть разделена между несколькими потоками без надлежащего синхронизированного блока, тогда как Hashtable синхронизирована и, следовательно, является потокобезопасной.
Нулевые ключи и нулевые значения:
HashMap допускает один нулевой ключ и любое количество нулевых значений. Hashtable не допускает нулевые ключи или значения.
Повторение значений:
Итератор в HashMap является безотказным итератором, в то время как перечислитель для Hashtable — нет, и генерирует исключение ConcurrentModificationException, если какой-либо другой поток структурно модифицирует карту, добавляя или удаляя любой элемент, кроме собственного метода remove() Итератора.
Суперкласс и наследие:
HashMap является подклассом класса AbstractMap, тогда как Hashtable является подклассом класса Dictionary.
Производительность:
Поскольку HashMap не синхронизирован, он быстрее по сравнению с Hashtable.
См. http://modernpathshala.com/Article/1020/ разница-между-хэш-картой-и-хэш-таблицей-в-java для примеров и вопросов для интервью и викторины, связанной с коллекцией Java
Обратите внимание, что во многих ответах указано, что Hashtable синхронизирован. На практике это вам очень мало. Синхронизация методов доступа / мутатора остановит одновременное добавление или удаление двух потоков с карты, но в реальном мире вам часто потребуется дополнительная синхронизация.
Очень распространенная идиома - «проверить, затем поместить», т.е. найти запись в Map
и добавить ее, если она еще не существует. Это ни в коем случае не атомарная операция, независимо от того, используете ли вы Hashtable
или HashMap
.
Эквивалентно синхронизированный HashMap
можно получить:
Collections.synchronizedMap(myMap);
Но для корректной реализации этой логики вам потребуется дополнительная синхронизация формы:
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
Даже перебор записей Hashtable
(или HashMap
, полученных Collections.synchronizedMap
) не является потокобезопасным, если вы также не защитите Map
от изменения посредством дополнительной синхронизации.
Реализации ConcurrentMap
интерфейс (например, ConcurrentHashMap
) решить некоторые из этих проблем, включив поточно-безопасную семантику проверки и действия , например:
ConcurrentMap.putIfAbsent(key, value);
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.
Помимо всех других важных аспектов, уже упомянутых здесь, API коллекций (например, интерфейс карты) постоянно модифицируется, чтобы соответствовать «последним и наиболее значительным» дополнениям к спецификации Java.
Например, сравните итерацию Java 5 Map:
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 они не появятся ... :(
Будут ли улучшения коллекции Project Coin в JDK8?
Hashtable
не реализует ни Map
, ни Iterable
(что требуется для "нового" синтаксиса foreach). Однако Hashtable.keySet()
возвращает Set
, что действительно допускает такой синтаксис.
Map
... рад, что его исправили после стольких лет невежества.
Hashtable
синхронизируется, а HashMap
- нет. Это делает Hashtable
медленнее, чем Hashmap
.
Для однопоточных приложений используйте HashMap
, поскольку в остальном они одинаковы с точки зрения функциональности.
HashTable синхронизируется, если вы его используете. в одном потоке вы можете использовать HashMap, это несинхронизированная версия. Несинхронизированные объекты часто немного более производительны. Между прочим, если несколько потоков обращаются к HashMap одновременно, и хотя бы один из потоков структурно модифицирует карту, она должна быть синхронизирована извне. Вы можете обернуть несинхронизированную карту в синхронизированную, используя:
Map m = Collections.synchronizedMap(new HashMap(...));
HashTable может содержать только ненулевой объект в качестве ключа или значения. HashMap может содержать один нулевой ключ и нулевые значения.
Итераторы, возвращаемые Map, являются отказоустойчивыми, если карта структурно изменена в любое время после создания итератора любым способом, кроме как с помощью собственного метода удаления итератора, итератор выдаст
ConcurrentModificationException
. Таким образом, перед лицом одновременной модификации итератор быстро и чисто дает сбой, а не рискует произвольным, недетерминированным поведением в неопределенное время в будущем. Поскольку перечисления, возвращаемые методами ключей и элементов Hashtable, не являются отказоустойчивыми.HashTable и HashMap являются членами платформы коллекций Java (начиная с платформы Java 2 v1.2, HashTable был модифицирован для реализации интерфейса Map).
HashTable считается устаревшим кодом, в документации рекомендуется использовать ConcurrentHashMap вместо Hashtable, если требуется потокобезопасная высокопараллельная реализация.
HashMap не гарантирует порядок, в котором возвращаются элементы. Для HashTable, я думаю, это то же самое, но я не совсем уверен, я не нахожу ресурсов, которые четко заявляют об этом.
HashMap
эмулируется и поэтому может использоваться в GWT client code
, тогда как Hashtable
- нет.
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.
ConcurrentMap
здесь не необходим, поскольку в вопросе говорится, что «беспоточные приложения» означают, что многопоточность / параллелизм не является проблемой.HashTable
, традиционно выбиралась только из-за частичной защиты многопоточности. Но это было устраненоConcurrentHashMap
, поэтому это обычно считается устаревшим. Обычно рекомендуется выбирать междуHashMap
илиConcurrentHashMap
." И я считаю, что это разумный комментарий, если она это имела в виду.