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

avatar
dmanxiii
2 сентября 2008 в 20:12
1613649
37
4009
Источник
MissFiona
9 апреля 2017 в 22:10
24

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

Basil Bourque
29 декабря 2019 в 01:11
4

@MissFiona Нет, ConcurrentMap здесь не требуется , поскольку в вопросе говорится, что «непоточные приложения» означают, что многопоточность / параллелизм не является проблемой.

Ответы (37)

avatar
Josh Brown
2 сентября 2008 в 23:02
4002

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

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

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

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

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

Rok Strniša
22 ноября 2011 в 18:48
103

Если вы хотите сделать HashMap поточно-ориентированным, используйте Collections.synchronizedMap().

erickson
16 марта 2012 в 17:19
309

Я также хотел бы отметить, что наивный подход к безопасности потоков в Hashtable («синхронизация каждого метода должна позаботиться о любых проблемах параллелизма!») Делает его очень хуже для многопоточных приложений. Лучше внешне синхронизировать HashMap (и подумать о последствиях) или использовать реализацию ConcurrentMap (и использовать ее расширенный API для параллелизма). Итог: единственная причина использовать Hashtable - это когда это требуется для устаревшего API (примерно с 1996 г.).

Gaurava Agarwal
27 июня 2016 в 09:00
8

HashMap дает программистам гибкость при написании кода threadSafe, когда они его действительно используют. Редко случалось, что мне требовались потокобезопасные коллекции, такие как ConcurrentHashMap или HashTable. Что мне нужно, так это определенный набор функций или определенных операторов в синхронизированном блоке, чтобы быть потокобезопасным.

Maneesh Kumar
30 марта 2018 в 03:45
4

Hashtable устарела, и мы используем HashMap для небезопасной среды. Если вам нужна потокобезопасность, вы можете использовать Collections.synchronizedMap () или использовать ConcurrentHashMap, что более эффективно, чем хеш-таблица.

Jilles van Gurp
19 мая 2018 в 08:11
4

Он устарел, но не устарел, и мне интересно, почему это так. Я предполагаю, что удаление этого класса (и Vector по тем же причинам) нарушит слишком много существующего кода, а аннотирование с помощью @Deprecated будет означать намерение удалить код, которого, по-видимому, нет.

rashid
25 июня 2018 в 07:25
1

Вы также можете использовать ConcurrentSkipListMap (docs.oracle.com/javase/10/docs/api/java/util/concurrent/…). Это потокобезопасная коллекция, аналогичная ConcurrentHashMap, и эта карта сортируется в соответствии с естественным порядком ее ключей или компаратором, предоставленным во время создания карты.

Gajraj Tanwar
3 мая 2021 в 10:09
1

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

avatar
Endrit Sheholli
9 июля 2021 в 11:51
0

HashMap и Hashtable хранят пары ключ / значение в хэш-таблице. При использовании Hashtable или HashMap мы указываем объект, который используется в качестве ключа, и значение, которое вы хотите связать с этим ключом. Затем ключ хешируется, и полученный хеш-код используется в качестве индекса, по которому значение сохраняется в таблице. Пример кода Java.

// A sample Java program to demonstrate HashMap and HashTable
import java.util.*;
import java.lang.*;
import java.io.*;
 
// Name of the class has to be "Main" only if the class is public
class Ideone
{
    public static void main(String args[])
    {
        // hashtable
        Hashtable<Integer,String> ht=new Hashtable<Integer,String>();
        ht.put(101," test");
        ht.put(101,"test1");
        ht.put(102,"test2");
        ht.put(103,"test3");
        System.out.println("-------------Hash table--------------");
        for (Map.Entry m:ht.entrySet()) {
            System.out.println(m.getKey()+" "+m.getValue());
        }
 
        // hashmap
        HashMap<Integer,String> hm=new HashMap<Integer,String>();
        hm.put(100,"test");
        hm.put(104,"test1"); 
        hm.put(101,"test2");
        hm.put(102,"test3");
        System.out.println("-----------Hash map-----------");
        for (Map.Entry m:hm.entrySet()) {
            System.out.println(m.getKey()+" "+m.getValue());
        }
    }
}

---- Hash table --- 103 test3 102 test2 101 test1
---- Hash map   --- 100 test 101 test2 102 test3 104 test1

Hashmap против Hashtable :

  1. HashMap не синхронизирован. Он не является потокобезопасным и не может использоваться многими потоками без надлежащего кода синхронизации, тогда как Hashtable синхронизируется. Он является потокобезопасным и может использоваться многими потоками.
  2. HashMap допускает один нулевой ключ и несколько нулевых значений, тогда как Hashtable не допускает никаких нулевых ключей или значений.
  3. HashMap обычно предпочтительнее HashTable, если синхронизация потоков не требуется Почему HashTable не допускает null, а HashMap - нет? Чтобы успешно хранить и извлекать объекты из HashTable, объекты, используемые в качестве ключей, должны реализовывать метод hashCode и метод equals. Поскольку null не является объектом, он не может реализовать эти методы. HashMap - это расширенная версия и улучшение Hashtable. HashMap был создан позже.
avatar
user3552342
12 марта 2021 в 18:05
0

Хеш-таблица является поточно-ориентированной и может совместно использоваться несколькими потоками в приложении.

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

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

Hashtable вообще не допускает null.

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

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

avatar
DeC
30 октября 2019 в 11:32
9

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

enter image description here

user2485429
23 марта 2021 в 12:19
0

Я думаю, это скопировано с javaconceptoftheday.com/…

avatar
Yash
4 января 2018 в 11:58
26

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

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


« Член суперкласса, унаследованного и коллекционного каркаса

Hashtable - это устаревший класс, представленный в JDK1.0, который является подклассом класса Dictionary. Из JDK1.2 Hashtable переработан для реализации интерфейса Map, чтобы сделать его членом структуры коллекции. 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). Где as Hashtable создает пустую хеш-таблицу с начальной емкостью по умолчанию (11) и коэффициентом загрузки / коэффициентом заполнения (0,75).

Hash Map & Hashtable

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

HashMap, Hashtable в случае хеш-коллизии они сохраняют записи карты в связанных списках. С Java8 для HashMap , если хэш-сегмент превышает определенный порог, этот сегмент переключится с linked list of entries to a balanced tree. которые улучшают производительность в худшем случае с O (n) до O (log n). При преобразовании списка в двоичное дерево хэш-код используется как переменная ветвления. Если в одной корзине есть два разных хэш-кода, один считается большим и идет справа от дерева, а другой - слева. Но когда оба хэш-кода равны, 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 является непостоянным, что обеспечивает согласованность с мелким зерном для согласованных модификаций и последующих чтений; каждое чтение отражает последнее завершенное обновление

  • Итераторы и перечисления являются отказоустойчивыми - отражают состояние в определенный момент с момента создания итератора / перечисления; это позволяет одновременно читать и изменять за счет снижения согласованности. Они не генерируют исключение 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 не допускает даже одного нулевого ключа и нулевого значения, если нулевым ключом или значением является исключение NullPointerException. Пример

« Синхронизированный, потокобезопасный

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

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

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


@See

avatar
KIBOU Hassan
21 апреля 2017 в 15:41
0

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

avatar
roottraveller
6 марта 2017 в 10:09
77

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

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 проходит через перечислитель и итератор.
  7. Перечислитель в Hashtable не работает до отказа.
  8. Hashtable наследует класс Dictionary.

Дополнительная литература В чем разница между HashMap и Hashtable в Java?

enter image description here

prayagupd
13 марта 2017 в 02:36
0

В значительной степени освещено в этом ответе (дубликат) - coderhelper.com/a/39785829/432903.

IgorGanapolsky
24 марта 2017 в 19:29
0

Почему вы говорите ~ " Hashtable - это устаревший класс "? Где для этого есть подтверждающая документация.

roottraveller
29 марта 2017 в 09:48
3

@IgorGanapolsky, вы можете прочитать это - coderhelper.com/questions/21086307/…

Abdul
30 июля 2018 в 02:05
0

Поддержка HashMap дороже, чем TreeMap. Потому что HashMap создает ненужные дополнительные ведра.

thomas.schuerger
4 февраля 2021 в 15:15
0

LinkedHashMap имеет двусвязный список записей, а не сегментов. Сегменты доступны через индексы массива и не нуждаются в связывании.

avatar
Kostas Chalkias
4 мая 2016 в 15:04
17

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

O (журнал (n)) для HashMap Vs O (n) в Hashtable.

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

К вашему сведению, в настоящее время

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

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

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

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

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

Итерация значений :

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

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

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

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

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

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

avatar
IntelliJ Amiya
10 февраля 2015 в 07:44
9

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));

    }
}
avatar
Rahul Tripathi
27 августа 2014 в 11:29
17

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);
avatar
Night0
17 августа 2014 в 09:58
6

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

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.

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

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

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

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

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

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

Map m = Collections.synchronizedMap(hashMap);

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

IgorGanapolsky
24 марта 2017 в 19:27
0

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

avatar
JegsVala
5 июля 2014 в 06:27
10

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.

Ioannis Sermetziadis
25 октября 2017 в 05:42
2

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

avatar
pierrotlefou
25 марта 2014 в 08:58
133

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

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

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

enter image description here

avatar
Shreyos Adikari
18 марта 2014 в 21:46
13

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

  1. Первое и наиболее существенное различие между Hashtable и HashMap заключается в том, что HashMap не является потокобезопасным, а Hashtable - потокобезопасным набором.

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

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

avatar
PetarMI
7 марта 2014 в 15:02
4

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

avatar
user1923551
11 декабря 2013 в 12:45
15

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

  1. Карты позволяют вам перебирать и извлекать ключи, значения и обе пары ключ-значение, а у HashTable нет всех этих возможностей.
  2. В Hashtable есть функция contains (), которую очень сложно использовать. Потому что значение содержит несколько отклонений. Значит ли это содержит ключ или содержит значение? сложно понять. То же самое и в Maps, у нас есть функции ContainsKey () и ContainsValue (), которые очень легко понять.
  3. В hashmap вы можете безопасно удалить элемент во время итерации. где это невозможно в хэш-таблицах.
  4. Хеш-таблицы по умолчанию синхронизированы, поэтому их можно легко использовать с несколькими потоками. Где, поскольку HashMaps не синхронизируются по умолчанию, поэтому могут использоваться только с одним потоком. Но вы все равно можете преобразовать HashMap в синхронизированный с помощью функции synchronizedMap (Map m) класса утилиты Collections.
  5. HashTable не допускает пустые ключи или нулевые значения. Где, поскольку HashMap допускает один нулевой ключ и несколько нулевых значений.
avatar
Ekanta Swain
23 июля 2013 в 15:50
3

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

avatar
pong
15 июля 2013 в 09:54
5

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

IgorGanapolsky
24 марта 2017 в 19:04
0

Это исчерпывающее описание различий между двумя API?

pong
24 марта 2017 в 19:41
0

Да (sic!). Это все, что разработчики GWT должны знать об этом.

avatar
jontejj
15 апреля 2013 в 14:49
10

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

jontejj
7 августа 2015 в 08:29
0

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

avatar
Ankit
31 января 2013 в 13:41
12

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

Хеш-таблица: это унаследованный класс, который распознается в рамках коллекции.

manikant gautam
16 октября 2019 в 10:48
0

Если да, то это должно быть в комментариях, а не в качестве ответа.

avatar
raja
22 января 2013 в 05:31
11
  1. Hashtable синхронизируется, а HashMap - нет.
  2. Другое отличие состоит в том, что итератор в HashMap является отказоустойчивым. а перечислитель для Hashtable - нет. Если вы измените карту во время итерации вы узнаете.
  3. HashMap допускает в нем нулевые значения, а Hashtable - нет.
Pankaj
28 января 2013 в 21:13
4

Итератор HashMap работает без сбоев, но не без сбоев. Вот почему у нас есть ConcurrentHashMap, который позволяет изменять во время итерации. Отметьте этот пост journaldev.com/122/…

Gaurav
18 августа 2020 в 12:22
0

@Pankaj Совершенно верно.

avatar
SkyWalker
10 декабря 2012 в 08:57
30

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

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

>

avatar
Sujan
20 ноября 2012 в 05:35
67

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

Матрица сбора Java

avatar
user1506047
9 августа 2012 в 12:28
3

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

IgorGanapolsky
24 марта 2017 в 19:03
5

Что означает ~ " свобода синхронизации "?

avatar
alain.janinm
29 апреля 2012 в 13:57
30
  • HashTable синхронизирован, если вы используете его в одном потоке, вы можете использовать HashMap, который является несинхронизированной версией. Несинхронизированные объекты часто немного более производительны. Между прочим, если несколько потоков обращаются к HashMap одновременно, и хотя бы один из потоков структурно модифицирует карту, она должна быть синхронизирована извне. Вы можете обернуть несинхронизированную карту в синхронизированную, используя:

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

avatar
pwes
12 января 2012 в 09:17
36

Помимо всех других важных аспектов, уже упомянутых здесь, 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 нам также обещают иметь возможность создавать и получать доступ к HashMap, как в старых добрых языках сценариев:

Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];

Обновление: Нет, они не приземлятся в 1.8 ... :(

Будут ли улучшения коллекции Project Coin в JDK8?

avatar
sravan
4 октября 2011 в 06:39
206

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

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

Примечание о некоторых важных терминах:

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

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

Map m = Collections.synchronizeMap(hashMap);

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

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

Stephen C
9 сентября 2013 в 08:05
21

Этот ответ содержит как минимум 2 существенные фактические неточности. Это определенно НЕ заслуживает такого количества голосов.

Stephen C
9 сентября 2013 в 08:14
63

1) Итераторы HashMap НЕ являются отказоустойчивыми. Они безотказны. Между этими двумя терминами существует огромная разница в значении. 2) Нет операции set на HashMap. 3) Операция put(...) не вызовет IllegalArgumentException, если было предыдущее изменение. 4) Отказоустойчивое поведение HashMap также происходит при изменении сопоставления. 5) Безотказное поведение гарантировано . (Что не гарантируется, так это поведение HashTable при одновременном изменении. Фактическое поведение ... непредсказуемо.)

Stephen C
9 сентября 2013 в 08:16
28

6) Hashtable также не гарантирует, что порядок элементов карты будет стабильным с течением времени. (Возможно, вы путаете Hashtable с LinkedHashMap.)

user4229245
4 мая 2015 в 22:26
4

Кто-нибудь еще действительно обеспокоен тем, что в наши дни студенты получают ошибочную идею о том, что получение «синхронизированных версий» коллекций каким-то образом означает, что вам не нужно внешне синхронизировать составные операции? Мой любимый пример - thing.set(thing.get() + 1);, который чаще всего застает новичков врасплох как совершенно незащищенный, особенно если get() и set() - это синхронизированные методы. Многие из них ждут волшебства.

Abdul
30 июля 2018 в 01:56
0

Итераторы на HashMap не безотказны

avatar
Neerja
8 сентября 2011 в 06:40
36

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

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

avatar
aberrant80
25 июня 2009 в 01:46
387

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

Kip
19 января 2010 в 22:09
105

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

pwes
12 января 2012 в 08:13
16

@ aberrant80: к сожалению, у вас нет выбора между ними, и вам нужно использовать Hashtable при программировании для J2ME ...

anon58192932
22 января 2016 в 20:40
6

этот ответ следует удалить. он содержит неверную информацию и имеет много положительных отзывов.

GC_
14 октября 2016 в 15:39
0

@ anon58192932 Можно ли отредактировать вопрос, чтобы исправить?

anon58192932
14 октября 2016 в 20:05
1

Мы должны привлечь внимание автора @ aberrant80 или администратора, отметив его. Пометка может помочь - сейчас попробую.

avatar
serg10
3 сентября 2008 в 11:00
730

Обратите внимание, что во многих ответах указано, что 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) решают некоторые из этих проблем, включая потокобезопасную проверку <670> такую ​​семантику как:

ConcurrentMap.putIfAbsent(key, value);
Chris K
22 апреля 2009 в 22:03
56

Также обратите внимание, что если HashMap изменяется, итераторы, указывающие на него, становятся недействительными.

telebog
11 ноября 2011 в 16:48
3

Так есть ли разница между синхронизированным (myMap) {...} и ConcurrentHashMap с точки зрения безопасности потоков?

Love Hasija
20 сентября 2012 в 10:21
3

Совершенно верно, я пытался объяснить то же самое здесь .. lovehasija.com/2012/08/16/…

Matt Stephenson
3 октября 2013 в 18:49
0

@Bhushan: он будет выбрасывать изо всех сил, это не гарантированное поведение: docs.oracle.com/javase/7/docs/api/java/util/HashMap.html

Hot Licks
20 августа 2014 в 15:34
0

Находясь в составе группы разработчиков JVM в течение нескольких лет, я могу заявить, что внутренняя синхронизация Hashtable, по крайней мере, полезна для того, чтобы правильно указывать пальцем на код клиента, когда он пишет изворотливый параллельный код. Мы получили несколько жалоб на сбои внутри HashMap (и, следовательно, «очевидно» ошибку JDK / JVM), когда причиной была одновременная модификация.

avatar
Apocalisp
2 сентября 2008 в 23:14
137

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

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

prap19
19 ноября 2011 в 14:55
0

Это действительно имеет смысл. ConcurrentHashMaps дает вам свободу синхронизации, а отладка намного проще.

user6552957
1 сентября 2018 в 19:23
1

Это специфично для Java или для всей реализации хэш-карты.

avatar
Tim Howland
2 сентября 2008 в 22:38
18

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

avatar
matt b
2 сентября 2008 в 20:30
67

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

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

Pacerier
1 ноября 2011 в 20:22
3

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

Majid Ali Khan
23 мая 2019 в 11:25
1

@Pacerier HashTable устарел, начиная с Java 1.7.

avatar
Miles D
2 сентября 2008 в 20:25
51

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

avatar
izb
2 сентября 2008 в 20:22
36

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

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

avatar
pkaeding
2 сентября 2008 в 20:14
29

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

Bart van Heukelom
18 декабря 2010 в 01:44
5

На самом деле это не предотвращает, а просто обнаруживает и выдает ошибку.

pkaeding
1 января 2011 в 01:46
1

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

cHao
18 апреля 2011 в 14:03
0

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