¿Diferencias entre HashMap y Hashtable?

3751

¿Cuáles son las diferencias entre a HashMapy a Hashtableen Java?

¿Cuál es más eficiente para aplicaciones sin rosca?

dmanxiii
fuente
17
HashTable está obsoleto en Java 1.7 y se recomienda usar la implementación de ConcurrentMap
MissFiona
@MissFiona No, noConcurrentMap es necesario aquí, ya que la Pregunta dice "aplicaciones sin subprocesos", lo que significa que el enhebrado / concurrencia no es un problema.
Basil Bourque

Respuestas:

3775

Hay varias diferencias entre HashMapy Hashtableen Java:

  1. Hashtableestá sincronizado , mientras HashMapque no lo está. Esto HashMapmejora las aplicaciones sin subprocesos, ya que los objetos no sincronizados suelen funcionar mejor que los sincronizados.

  2. Hashtableno permite nullclaves o valores. HashMappermite una nullclave y cualquier cantidad de nullvalores.

  3. Una de las subclases de HashMap es LinkedHashMap, por lo que en el caso de que desee un orden de iteración predecible (que es el orden de inserción por defecto), puede cambiar fácilmente el HashMappor a LinkedHashMap. Esto no sería tan fácil si estuviera usando Hashtable.

Dado que la sincronización no es un problema para usted, lo recomendaría HashMap. Si la sincronización se convierte en un problema, también puede mirar ConcurrentHashMap.

Josh Brown
fuente
84
Si desea hacer un HashMap seguro para subprocesos, use Collections.synchronizedMap().
Rok Strniša
275
También quisiera comentar que el enfoque ingenuo para la seguridad de subprocesos en Hashtable("¡sincronizar cada método debería ocuparse de cualquier problema de concurrencia!") Lo hace mucho peor para las aplicaciones de subprocesos. Es mejor sincronizar externamente un HashMap(y pensar en las consecuencias), o usar una ConcurrentMapimplementación (y explotar su API extendida para la concurrencia). En pocas palabras: la única razón para usar Hashtablees cuando una API heredada (desde aproximadamente 1996) lo requiere.
erickson
8
HashMap le da flexibilidad al programador para escribir código threadSafe cuando realmente lo usan. Raramente sucedía que necesitaba una colección segura para subprocesos como ConcurrentHashMap o HashTable. Lo que necesitaba es cierto conjunto de funciones o ciertas declaraciones en un bloque sincronizado para ser seguro.
Gaurava Agarwal
2
Hashtable es obsoleto y estamos utilizando HashMap para entornos no seguros para subprocesos. Si necesita seguridad de subprocesos, puede usar Collections.synchronizedMap () o usar ConcurrentHashMap, que es más eficiente que la tabla hash.
Maneesh Kumar
1
Es obsoleto pero no está en desuso y me pregunto por qué es así. Supongo que eliminar esta clase (y Vector por las mismas razones) rompería demasiado código existente y anotar con @Deprecated implicaría una intención de eliminar el código, que aparentemente no está allí.
Jilles van Gurp
682

Tenga en cuenta que muchas de las respuestas indican que Hashtable está sincronizado. En la práctica esto te compra muy poco. La sincronización está en los métodos de acceso / mutación para que dos hilos se agreguen o se eliminen del mapa simultáneamente, pero en el mundo real a menudo necesitará una sincronización adicional.

Un modismo muy común es "verificar luego poner", es decir, buscar una entrada en el Map, y agregarlo si aún no existe. Esto no es de ninguna manera una operación atómica, ya sea que use Hashtableo HashMap.

Se HashMappuede obtener una sincronización equivalente mediante:

Collections.synchronizedMap(myMap);

Pero para implementar correctamente esta lógica, necesita sincronización adicional del formulario:

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

Incluso iterar sobre Hashtablelas entradas de un (o un HashMapobtenido por Collections.synchronizedMap) no es seguro para subprocesos a menos que también evite que Mapse modifique mediante una sincronización adicional.

Las implementaciones de la ConcurrentMapinterfaz (por ejemplo ConcurrentHashMap) resuelven algo de esto mediante la inclusión de semánticas seguras para comprobar y luego actuar como:

ConcurrentMap.putIfAbsent(key, value);
serg10
fuente
53
También tenga en cuenta que si se modifica un HashMap, los iteradores que apuntan a él se invalidan.
Chris K
3
Entonces, ¿hay alguna diferencia entre sincronizado (myMap) {...} y ConcurrentHashMap en términos de seguridad de subprocesos?
telebog
3
Muy cierto, traté de explicar lo mismo aquí ... lovehasija.com/2012/08/16/…
Love Hasija
@Bhushan: lanzará con el mejor esfuerzo, esto no es un comportamiento garantizado: docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Matt Stephenson
Después de haber estado en medio de un equipo de desarrollo de JVM durante varios años, puedo afirmar que la sincronización interna de Hashtable es al menos útil para señalar correctamente el código del cliente cuando escribe código concurrente dudoso. Recibimos varias quejas de fallas dentro de HashMap (y por lo tanto "obviamente" un error JDK / JVM), cuando la causa fue una modificación concurrente.
Hot Licks
363

Hashtablese considera código heredado. No hay nada de eso Hashtableque no se pueda hacer usando HashMapo derivaciones de HashMap, por lo que para el nuevo código, no veo ninguna justificación para volver a hacerlo Hashtable.

aberrante80
fuente
101
De Hashtable javadoc (énfasis agregado): "A partir de la plataforma Java 2 v1.2, esta clase se actualizó para implementar la interfaz de Mapa, haciéndola miembro del Marco de Colecciones de Java ". Sin embargo, tiene razón en que es un código heredado. Todos los beneficios de la sincronización se pueden obtener de manera más eficiente con Collections.synchronizedMap (HashMap). (Similar a Vector siendo una versión heredada de Collections.synchronizedList (ArrayList).)
Kip
15
@ aberrant80: desafortunadamente no tienes elección entre los dos y tienes que usar Hashtable al programar para J2ME ...
pwes
66
Esta respuesta debe ser eliminada. contiene información incorrecta y tiene muchos votos a favor.
anon58192932
@ anon58192932 ¿Es posible editar la pregunta para solucionarlo?
GC_
1
Tenemos que llamar la atención del póster @ aberrant80 o de un administrador marcando. Marcar podría ayudar, lo intentaré ahora.
anon58192932
189

Esta pregunta a menudo se hace en una entrevista para verificar si el candidato comprende el uso correcto de las clases de recolección y si conoce las soluciones alternativas disponibles.

  1. La HashMapclase es más o menos equivalente a Hashtable, excepto que no está sincronizada y permite valores nulos. ( HashMappermite valores nulos como clave y valor, mientras Hashtableque no permite nulls).
  2. HashMap no garantiza que el orden del mapa se mantendrá constante en el tiempo.
  3. HashMapno está sincronizado mientras que Hashtableestá sincronizado.
  4. El iterador en el HashMapes a prueba de fallas, mientras que el enumerador para el Hashtableno lo es y arroja ConcurrentModificationExceptionsi cualquier otro hilo modifica estructuralmente el mapa agregando o eliminando cualquier elemento, excepto Iteratorel propio remove() método. Pero este no es un comportamiento garantizado y JVM lo hará con el mejor esfuerzo.

Nota sobre algunos términos importantes:

  1. Sincronizado significa que solo un subproceso puede modificar una tabla hash en un punto del tiempo. Básicamente, significa que cualquier subproceso antes de realizar una actualización en un Hashtabletendrá que adquirir un bloqueo en el objeto, mientras que otros esperarán a que se libere el bloqueo.
  2. Fail-safe es relevante dentro del contexto de los iteradores. Si se ha creado un iterador en un objeto de colección y algún otro hilo intenta modificar el objeto de colección "estructuralmente", se lanzará una excepción de modificación concurrente. Sin embargo, es posible que otros hilos invoquen el setmétodo ya que no modifica la colección "estructuralmente". Sin embargo, si antes de llamar set, la colección se ha modificado estructuralmente, IllegalArgumentExceptionserá arrojada.
  3. La modificación estructural significa eliminar o insertar un elemento que podría cambiar efectivamente la estructura del mapa.

HashMap puede ser sincronizado por

Map m = Collections.synchronizeMap(hashMap);

El mapa proporciona vistas de colección en lugar de soporte directo para la iteración a través de objetos de enumeración. Las vistas de colección mejoran en gran medida la expresividad de la interfaz, como se describe más adelante en esta sección. Map le permite iterar sobre claves, valores o pares clave-valor; HashtableNo proporciona la tercera opción. El mapa proporciona una forma segura de eliminar entradas en medio de la iteración; HashtableNo. Finalmente, Map corrige una deficiencia menor en la Hashtableinterfaz. Hashtabletiene un método llamado contiene, que devuelve verdadero si Hashtablecontiene un valor dado. Dado su nombre, esperaría que este método devuelva verdadero si Hashtablecontuviera una clave dada, porque la clave es el mecanismo de acceso principal para a . Además, esto mejora la consistencia de la interfaz - paralelosHashtable . La interfaz de Map elimina esta fuente de confusión al renombrar el método containsValuecontainsValuecontainsKey.

La interfaz del mapa

sravan
fuente
19
Esta respuesta contiene al menos 2 inexactitudes de hecho significativas. Ciertamente NO merece tantos votos a favor.
Stephen C
58
1) Los iteradores de HashMap NO son a prueba de fallas. Son a prueba de fallas. Hay una gran diferencia de significado entre esos dos términos. 2) No hay setoperación en a HashMap. 3) La put(...)operación no se lanzará IllegalArgumentExceptionsi hubo un cambio previo. 4) El comportamiento de falla rápida HashMap también se produce si cambia una asignación. 5) El comportamiento a prueba de fallas está garantizado. (Lo que no está garantizado es el comportamiento de un HashTablesi realiza una modificación concurrente. El comportamiento real es ... impredecible)
Stephen C
25
6) Hashtabletampoco garantiza que el orden de los elementos del mapa sea estable en el tiempo. (Quizás te estés confundiendo Hashtablecon LinkedHashMap.)
Stephen C
44
¿Alguien más está realmente preocupado de que los estudiantes en estos días tengan la idea errónea de que obtener "versiones sincronizadas" de las colecciones de alguna manera significa que no tiene que sincronizar externamente las operaciones compuestas? Mi ejemplo favorito de este ser thing.set(thing.get() + 1);la que más a menudo que no coge por sorpresa novatos como totalmente desprotegidos, especialmente si el get()y set()son métodos sincronizados. Muchos de ellos esperan magia.
Iterators en HashMap no es a prueba de fallas
Abdul
130

HashMap: Una implementación de la Mapinterfaz que utiliza códigos hash para indexar una matriz. Hashtable: Hola, 1998 llamado. Quieren recuperar sus API de colecciones.

En serio, es mejor que te mantengas alejado de Hashtabletodo. Para aplicaciones de subproceso único, no necesita la sobrecarga adicional de sincronización. Para aplicaciones altamente concurrentes, la sincronización paranoica puede conducir a la inanición, puntos muertos o pausas innecesarias de recolección de basura. Como señaló Tim Howland, podría usar ConcurrentHashMapen su lugar.

Apocalipsis
fuente
Esto realmente tiene sentido. ConcurrentHashMaps le brinda libertad de sincronización y depuración es mucho más fácil.
prap19
1
¿Es esto específico de Java o de toda la implementación del mapa hash?
125

Tenga en cuenta que HashTableera una clase heredada antes de que se introdujera Java Collections Framework (JCF) y que luego se modificó para implementar la Mapinterfaz. Así fue Vectory Stack.

Por lo tanto, siempre manténgase alejado de ellos en el nuevo código, ya que siempre hay una mejor alternativa en el JCF como otros han señalado.

Aquí está la hoja de trucos de la colección Java que le resultará útil. Observe que el bloque gris contiene la clase heredada HashTable, Vector y Stack.

ingrese la descripción de la imagen aquí

pierrotlefou
fuente
72

Hay muchas buenas respuestas ya publicadas. Estoy agregando algunos puntos nuevos y resumiéndolo.

HashMapy Hashtableambos se usan para almacenar datos en forma de clave y valor . Ambos utilizan la técnica de hashing para almacenar claves únicas. Pero hay muchas diferencias entre las clases HashMap y Hashtable que se dan a continuación.

HashMap

  1. HashMapno está sincronizado No es seguro para subprocesos y no se puede compartir entre muchos subprocesos sin un código de sincronización adecuado.
  2. HashMap permite una clave nula y múltiples valores nulos.
  3. HashMap es una nueva clase introducida en JDK 1.2.
  4. HashMap es rápido.
  5. Podemos HashMapsincronizarlo llamando a este código
    Map m = Collections.synchronizedMap(HashMap);
  6. HashMap es atravesado por Iterator.
  7. Iterator in HashMapes a prueba de fallos.
  8. HashMap hereda la clase AbstractMap.

Tabla de picadillo

  1. Hashtableestá sincronizado Es seguro para subprocesos y se puede compartir con muchos subprocesos.
  2. Hashtable no permite ninguna clave o valor nulo.
  3. Hashtable Es una clase heredada.
  4. Hashtable es lento.
  5. Hashtable está sincronizado internamente y no se puede desincronizar.
  6. Hashtable es atravesado por Enumerator e Iterator.
  7. El enumerador Hashtableno es a prueba de fallos.
  8. Hashtable hereda la clase Diccionario.

Lecturas adicionales ¿Cuál es la diferencia entre HashMap y Hashtable en Java?

ingrese la descripción de la imagen aquí

roottraveller
fuente
Bastante cubierto en esta respuesta (duplicado de) - stackoverflow.com/a/39785829/432903 .
prayagupd
¿Por qué dices ~ " Hashtable es una clase heredada "? ¿Dónde está la documentación de respaldo para eso?
IgorGanapolsky
2
@IgorGanapolsky puedes leer esto - stackoverflow.com/questions/21086307/…
roottraveller
Mantener HashMap es costoso que TreeMap. Porque HashMap crea cubos adicionales innecesarios.
Abdul
64

Además de lo que izb dijo, HashMappermite valores nulos, mientras Hashtableque no.

También tenga en cuenta que Hashtableextiende la Dictionaryclase, que como el estado de Javadocs , es obsoleta y ha sido reemplazada por la Mapinterfaz.

mate b
fuente
3
pero eso no hace que HashTable quede obsoleto, ¿verdad?
Pacerier
@Pacerier HashTable está obsoleto desde Java 1.7.
Majid Ali Khan
62

Echa un vistazo a este cuadro. Proporciona comparaciones entre diferentes estructuras de datos junto con HashMapy Hashtable. La comparación es precisa, clara y fácil de entender.

Matriz de colección de Java

Sujan
fuente
49

Hashtablees similar al HashMapy tiene una interfaz similar. Se recomienda que utilice HashMap, a menos que necesite soporte para aplicaciones heredadas o necesite sincronización, ya que los Hashtablesmétodos están sincronizados. Entonces, en su caso, ya que no es multihilo, HashMapses su mejor apuesta.

Miles D
fuente
36

Otra diferencia clave entre la tabla hash y el mapa hash es que Iterator en el HashMap es a prueba de fallas, mientras que el enumerador de la Hashtable no lo es y lanza ConcurrentModificationException si cualquier otro Thread modifica el mapa estructuralmente agregando o eliminando cualquier elemento, excepto el método remove () del Iterator. Pero este no es un comportamiento garantizado y JVM lo hará con el mejor esfuerzo ".

Mi fuente: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html

Neerja
fuente
36

Además de todos los otros aspectos importantes ya mencionados aquí, la API de colecciones (por ejemplo, la interfaz de mapa) se está modificando todo el tiempo para cumplir con las "últimas y mejores" adiciones a las especificaciones de Java.

Por ejemplo, compare la iteración de Java 5 Map:

for (Elem elem : map.keys()) {
  elem.doSth();
}

versus el viejo enfoque de Hashtable:

for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
  Elem elem = (Elem) en.nextElement();
  elem.doSth();
}

En Java 1.8 también se nos promete poder construir y acceder a HashMaps como en buenos y viejos lenguajes de scripting:

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

Actualización: No, no aterrizarán en 1.8 ... :(

¿Las mejoras de la colección de Project Coin estarán en JDK8?

pwes
fuente
34

Hashtableestá sincronizado, mientras HashMapque no lo está. Eso hace Hashtablemás lento que Hashmap.

Para las aplicaciones sin subprocesos, úselas HashMapya que de lo contrario son las mismas en términos de funcionalidad.

izb
fuente
30
  • HashTable está sincronizado, si lo está usando en un solo hilo, puede usar HashMap , que es una versión no sincronizada. Los objetos no sincronizados son a menudo un poco más efectivos. Por cierto, si varios subprocesos acceden a un HashMap al mismo tiempo, y al menos uno de los subprocesos modifica el mapa estructuralmente, debe sincronizarse externamente. Youn puede envolver un mapa no sincronizado en uno sincronizado usando:

    Map m = Collections.synchronizedMap(new HashMap(...));
  • HashTable solo puede contener objetos no nulos como clave o como valor. HashMap puede contener una clave nula y valores nulos.

  • Los iteradores devueltos por Map son a prueba de fallas, si el mapa se modifica estructuralmente en cualquier momento después de que se crea el iterador, de cualquier manera, excepto a través del método remove del propio iterador, el iterador arrojará un ConcurrentModificationException. Por lo tanto, frente a la modificación concurrente, el iterador falla de manera rápida y limpia, en lugar de arriesgarse a un comportamiento arbitrario, no determinista en un momento indeterminado en el futuro. Mientras que las Enumeraciones devueltas por los métodos de elementos y claves de Hashtable no son a prueba de fallas.

  • HashTable y HashMap son miembros de Java Collections Framework (desde la plataforma Java 2 v1.2, HashTable se actualizó para implementar la interfaz Map).

  • HashTable se considera código heredado, la documentación aconseja utilizar ConcurrentHashMap en lugar de Hashtable si se desea una implementación altamente concurrente segura para subprocesos.

  • HashMap no garantiza el orden en que se devuelven los elementos. Para HashTable, supongo que es lo mismo, pero no estoy completamente seguro, no encuentro recursos que lo indiquen claramente.

alain.janinm
fuente
30

HashMapy Hashtabletienen diferencias algorítmicas significativas también. Nadie ha mencionado esto antes, por eso lo menciono. HashMapconstruirá una tabla hash con una potencia de dos tamaños, la aumentará dinámicamente de modo que tenga como máximo unos ocho elementos (colisiones) en cualquier cubo y agitará los elementos muy bien para los tipos de elementos generales. Sin embargo, la Hashtableimplementación proporciona un control mejor y más fino sobre el hash si sabe lo que está haciendo, es decir, puede arreglar el tamaño de la tabla utilizando, por ejemplo, el número primo más cercano al tamaño de su dominio de valores y esto dará como resultado un mejor rendimiento que HashMap, es decir, menos colisiones para algunos casos

Aparte de las diferencias obvias discutidas extensamente en esta pregunta, veo el Hashtable como un automóvil de "manejo manual" donde tiene un mejor control sobre el hashing y el HashMap como el homólogo del "manejo automático" que generalmente funcionará bien.

Andante del cielo
fuente
27

Según la información aquí , recomendaría ir con HashMap. Creo que la mayor ventaja es que Java evitará que lo modifiques mientras lo iteras, a menos que lo hagas a través del iterador.

pkaeding
fuente
55
En realidad no lo impide, solo lo detecta y arroja un error.
Bart van Heukelom
1
Estoy bastante seguro de que arrojará una ConncurrentModificationException antes de que se modifique la colección subyacente, aunque podría estar equivocado.
pkaeding 01 de
Se tratará de detectar la modificación concurrente y lanzar una excepción. Pero si está haciendo algo con hilos, no puede hacer ninguna promesa. Absolutamente cualquier cosa puede suceder, incluida la rotura .
cHao
24

A Collection, a veces llamado contenedor, es simplemente un objeto que agrupa múltiples elementos en una sola unidad. Collections se utilizan para almacenar, recuperar, manipular y comunicar datos agregados. Un marco de colecciones W es una arquitectura unificada para representar y manipular colecciones.

El HashMap JDK1.2y Hashtable JDK1.0, ambos se usan para representar un grupo de objetos que están representados en <Key, Value>pares. Cada <Key, Value>par se llama Entryobjeto. La colección de entradas se refiere por el objeto de HashMapy Hashtable. Las claves de una colección deben ser únicas o distintivas. [ya que se utilizan para recuperar un valor mapeado de una clave particular. los valores en una colección se pueden duplicar.]


« Miembro de Superclass, Legacy y Collection Framework

Hashtable es una clase heredada introducida en JDK1.0, que es una subclase de la clase Diccionario. Desde JDK1.2Hashtable se rediseñó para implementar la interfaz de Mapa para hacer un miembro del marco de recopilación. HashMap es miembro de Java Collection Framework desde el comienzo de su introducción en JDK1.2. HashMap es la subclase de la clase 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 { ... }

« Capacidad inicial y factor de carga

La capacidad es el número de cubos en la tabla hash, y la capacidad inicial es simplemente la capacidad en el momento en que se crea la tabla hash. Tenga en cuenta que la tabla hash está abierta: en el caso de un " hashcollision", un único depósito almacena múltiples entradas, que deben buscarse secuencialmente. El factor de carga es una medida de cuán llena se permite que llegue la tabla hash antes de que su capacidad aumente automáticamente.

HashMap construye una tabla hash vacía con la capacidad inicial predeterminada (16) y el factor de carga predeterminado (0.75). Donde como Hashtable construye una tabla hash vacía con una capacidad inicial predeterminada (11) y un factor de carga / relación de llenado (0.75).

Mapa de hash y tabla hash

« Modificación estructural en caso de colisión de hash

HashMap, Hashtableen caso de colisiones hash, almacenan las entradas del mapa en listas vinculadas. Desde Java8 paraHashMap si el depósito de hash crece más allá de cierto umbral, ese depósito cambiará de linked list of entries to a balanced tree. que mejoran el rendimiento en el peor de los casos de O (n) a O (log n). Al convertir la lista a árbol binario, el código hash se usa como una variable de ramificación. Si hay dos códigos hash diferentes en el mismo cubo, uno se considera más grande y va a la derecha del árbol y el otro a la izquierda. Pero cuando ambos códigos hash son iguales, HashMapsupone que las claves son comparables y compara la clave para determinar la dirección para que se pueda mantener un cierto orden. Es una buena práctica convertir las claves de HashMap una . Al agregar entradas si el tamaño del depósito alcanzaTREEIFY_THRESHOLD = 8 lista de entradas enlazadas convertibles comparables en un árbol equilibrado, al eliminar entradas de menos deTREEIFY_THRESHOLD y como máximo UNTREEIFY_THRESHOLD = 6, árbol equilibrado en una lista vinculada de entradas. Java 8 SRC , stackpost

« Repetición de vista de colección, Fail-Fast y Fail-Safe

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

Iteratores un fracaso en la naturaleza. es decir, arroja ConcurrentModificationException si se modifica una colección mientras se itera de otro modo que no sea su propio método remove (). Donde como Enumerationes a prueba de fallas en la naturaleza. No arroja ninguna excepción si una colección se modifica durante la iteración.

De acuerdo con Java API Docs, Iterator siempre se prefiere sobre la enumeración.

NOTA: La funcionalidad de la interfaz Enumeration está duplicada por la interfaz Iterator. Además, Iterator agrega una operación de eliminación opcional y tiene nombres de método más cortos. Las nuevas implementaciones deberían considerar usar Iterator en lugar de Enumeration.

En Java 5, se introdujo la interfaz ConcurrentMap : ConcurrentHashMapuna ConcurrentMapimplementación altamente concurrente de alto rendimiento respaldada por una tabla hash. Esta implementación nunca se bloquea al realizar recuperaciones y permite al cliente seleccionar el nivel de concurrencia para las actualizaciones. Está pensado como un reemplazo directo para Hashtable: además de implementar ConcurrentMap, es compatible con todos los métodos "heredados" propios de Hashtable.

  • HashMapEntryEl valor de cada s es volátil, lo que garantiza una consistencia de grano fino para modificaciones contenidas y lecturas posteriores; cada lectura refleja la actualización completada más recientemente

  • Los iteradores y las enumeraciones son a prueba de fallos, lo que refleja el estado en algún momento desde la creación del iterador / enumeración; Esto permite lecturas y modificaciones simultáneas a costa de una consistencia reducida. No lanzan ConcurrentModificationException. Sin embargo, los iteradores están diseñados para ser utilizados por un solo hilo a la vez.

  • Me gusta Hashtablepero HashMapno me gusta , esta clase no permite que se use nulo como clave o valor.

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

«« Claves nulas y valores nulos

HashMappermite un máximo de una clave nula y cualquier número de valores nulos. Donde as Hashtableno permite ni siquiera una sola clave nula y un valor nulo, si la clave o el valor nulo es entonces arroja NullPointerException.Ejemplo

«« Sincronizado, hilo seguro

Hashtableestá sincronizado internamente Por lo tanto, es muy seguro de usar Hashtableen aplicaciones de subprocesos múltiples. Donde como HashMapno está sincronizado internamente. Por lo tanto, no es seguro usarlo HashMapen aplicaciones de subprocesos múltiples sin sincronización externa. Puedes sincronizar externamenteHashMap utilizando el Collections.synchronizedMap()método

«« Rendimiento

Como Hashtableestá sincronizado internamente, esto hace que sea un Hashtablepoco más lento que elHashMap .


@Ver

Yash
fuente
18

Para las aplicaciones de subprocesos, a menudo puede salirse con la suya ConcurrentHashMap, depende de sus requisitos de rendimiento.

Tim Howland
fuente
17

1. HashmapyHashTable ambos almacenan clave y valor.

2. Hashmappuede almacenar una clave como null. Hashtableno puede almacenarnull .

3. HashMapno está sincronizado peroHashtable está sincronizado.

4. HashMapse puede sincronizar conCollection.SyncronizedMap(map)

Map hashmap = new HashMap();

Map map = Collections.SyncronizedMap(hashmap);
Rahul Tripathi
fuente
16

Además de las diferencias ya mencionadas, debe tenerse en cuenta que desde Java 8, HashMapreemplaza dinámicamente los nodos (lista vinculada) utilizados en cada cubo con TreeNodes (árbol rojo-negro), de modo que incluso si existen colisiones de hash altas, el peor de los casos cuando buscando es

O (log (n)) para HashMap Vs O (n) enHashtable .

* La mejora antes mencionada no se ha aplicado a Hashtabletodavía, pero sólo a HashMap, LinkedHashMapyConcurrentHashMap .

FYI, actualmente,

  • TREEIFY_THRESHOLD = 8 : si un depósito contiene más de 8 nodos, la lista vinculada se transforma en un árbol equilibrado.
  • UNTREEIFY_THRESHOLD = 6 : cuando un depósito se vuelve demasiado pequeño (debido a la eliminación o al cambio de tamaño), el árbol se convierte nuevamente en una lista vinculada.
Kostas Chalkias
fuente
14

Hay 5 diferenciaciones básicas con HashTable y HashMaps.

  1. Maps le permite iterar y recuperar claves, valores y ambos pares clave-valor, donde HashTable no tiene toda esta capacidad.
  2. En Hashtable hay una función contiene (), lo cual es muy confuso de usar. Porque el significado de contiene es ligeramente diferente. Si significa contiene clave o contiene valor? Difícil de entender. Lo mismo en Maps tenemos las funciones ContainsKey () y ContainsValue (), que son muy fáciles de entender.
  3. En hashmap puedes eliminar elementos mientras iteras de forma segura. donde como no es posible en tablas hash.
  4. Las HashTables están sincronizadas de forma predeterminada, por lo que se pueden usar con múltiples subprocesos fácilmente. Donde los HashMaps no están sincronizados de manera predeterminada, por lo que solo se pueden usar con un único subproceso. Pero aún puede convertir HashMap a sincronizado mediante el uso de la función synizedMap (Map m) de la clase de utilidades de Colecciones.
  5. HashTable no permitirá claves nulas o valores nulos. Donde como HashMap permite una clave nula y múltiples valores nulos.
usuario1923551
fuente
13

Mi pequeña contribución:

  1. La primera y más significativa diferencia entre Hashtabley HashMapes que HashMapno es segura para subprocesos, mientras que Hashtablees una colección segura para subprocesos.

  2. La segunda diferencia importante entre Hashtabley HashMapes el rendimiento, ya HashMapque no está sincronizado, funciona mejor que Hashtable.

  3. La tercera diferencia en Hashtablevs HashMapes que Hashtablees una clase obsoleta y que debería usar ConcurrentHashMapen lugar de Hashtableen Java.

Shreyos Adikari
fuente
11

HashMap: es una clase disponible dentro del paquete java.util y se usa para almacenar el elemento en formato de clave y valor.

Hashtable: es una clase heredada que se reconoce dentro del marco de recopilación.

Ankit
fuente
Si es así, debe aparecer en los comentarios, no como respuesta.
manikant gautam
10

HashTable es una clase heredada en el jdk que ya no debería usarse. Reemplace sus usos con ConcurrentHashMap . Si no necesita seguridad para subprocesos, use HashMap, que no es seguro para subprocesos pero es más rápido y usa menos memoria.

jontejj
fuente
Porque pensé que las otras respuestas, en ese momento, no descartaron HashTable pero explicaron que era seguro. La verdad es que tan pronto como vea HashTable en el código, debe reemplazarlo con ConcurrentHashMap sin omitir un latido. Y si la seguridad de los hilos no es una preocupación, HashMap puede usarse para mejorar un poco el rendimiento.
jontejj
10
  1. Hashtable está sincronizado mientras que HashMap que no lo está.
  2. Otra diferencia es que el iterador en el HashMapes a prueba de fallas mientras que el enumerador para elHashtable no lo es. Si cambia el mapa mientras itera, lo sabrá.
  3. HashMap permite valores nulos en él, mientras que Hashtable que no.
raja
fuente
3
El iterador HashMap es a prueba de fallas y no a prueba de fallas. Es por eso que tenemos ConcurrentHashMap que permite la modificación durante la iteración. Mira esta publicación journaldev.com/122/…
Pankaj
9

HashMap y HashTable

  • Algunos puntos importantes sobre HashMap y HashTable. por favor lea los detalles a continuación.

1) Hashtable y Hashmap implementan la interfaz java.util.Map 2) Tanto Hashmap como Hashtable es la colección basada en hash. y trabajando en hashing. Estas son similitudes de HashMap y HashTable.

  • ¿Cuál es la diferencia entre HashMap y HashTable?

1) La primera diferencia es que HashMap no es seguro para subprocesos, mientras que HashTable es ThreadSafe
2) HashMap es mejor en cuanto a rendimiento porque no es seguro para subprocesos. mientras que el rendimiento de Hashtable no es mejor porque es seguro para subprocesos. por lo que varios subprocesos no pueden acceder a Hashtable al mismo tiempo.

JegsVala
fuente
2
Votado a favor porque esta respuesta no es correcta en algunos aspectos. Hashtable no implementa la interfaz Map, sino que solo extiende la clase Dictionary, que está obsoleta.
Yannis Sermetziadis
8

Hashtable:

Hashtable es una estructura de datos que retiene los valores del par clave-valor. No permite nulo tanto para las claves como para los valores. Obtendrá un NullPointerExceptionsi agrega valor nulo. Está sincronizado Entonces viene con su costo. Solo un hilo puede acceder a HashTable en un momento particular.

Ejemplo :

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 es como Hashtable pero también acepta pares de valores clave. Permite nulo tanto para las claves como para los valores. Su rendimiento mejor es mejor que HashTable, porque esunsynchronized .

Ejemplo:

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

    }
}
IntelliJ Amiya
fuente
5

HashMapse emula y, por lo tanto, se puede usar GWT client codemientras Hashtableque no.

apestar
fuente
¿Es esa una descripción completa de las diferencias entre los dos apis?
IgorGanapolsky
Sí (sic!) Eso es todo lo que los desarrolladores de GWT necesitan saber al respecto.
pong
5

Tema antiguo y clásico, solo quiero agregar este útil blog que explica esto:

http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/

Blog de Manish Chhabra

Las 5 diferencias principales entre HashMap y Hashtable

HashMap y Hashtable implementan la interfaz java.util.Map, pero hay algunas diferencias que los desarrolladores de Java deben entender para escribir código más eficiente. A partir de la plataforma Java 2 v1.2, la clase Hashtable se actualizó para implementar la interfaz Map, convirtiéndola en miembro de Java Collections Framework.

  1. Una de las principales diferencias entre HashMap y Hashtable es que HashMap no está sincronizado, mientras que Hashtable está sincronizado, lo que significa que Hashtable es seguro para subprocesos y se puede compartir entre varios subprocesos, pero HashMap no se puede compartir entre varios subprocesos sin una sincronización adecuada. Java 5 introdujo ConcurrentHashMap, que es una alternativa de Hashtable y proporciona una mejor escalabilidad que Hashtable en Java. Sincronizado significa que solo un subproceso puede modificar una tabla hash en un punto del tiempo. Básicamente, significa que cualquier subproceso antes de realizar una actualización en una tabla hash tendrá que adquirir un bloqueo en el objeto, mientras que otros esperarán a que se libere el bloqueo.

  2. La clase HashMap es más o menos equivalente a Hashtable, excepto que permite valores nulos. (HashMap permite valores nulos como clave y valor, mientras que Hashtable no permite valores nulos).

  3. La tercera diferencia significativa entre HashMap frente a Hashtable es que Iterator en HashMap es un iterador rápido a prueba de fallas, mientras que el enumerador para Hashtable no lo es y arroja ConcurrentModificationException si cualquier otro Thread modifica el mapa estructuralmente agregando o eliminando cualquier elemento, excepto el propio removedor de Iterator ( ) método. Pero este no es un comportamiento garantizado y JVM lo hará con el mejor esfuerzo. Esta también es una diferencia importante entre Enumeration e Iterator en Java.

  4. Una diferencia notable más entre Hashtable y HashMap es que, debido a la seguridad de los subprocesos y la sincronización, Hashtable es mucho más lento que HashMap si se usa en un entorno de subprocesamiento único. Entonces, si no necesita sincronización y HashMap solo lo usa un subproceso, superará a Hashtable en Java.

  5. HashMap no garantiza que el orden del mapa se mantendrá constante a lo largo del tiempo.

Tenga en cuenta que HashMap puede ser sincronizado por

Map m = Collections.synchronizedMap(hashMap);

En resumen, existen diferencias significativas entre Hashtable y HashMap en Java, por ejemplo, seguridad y velocidad de subprocesos y, en función de eso, solo use Hashtable si realmente necesita seguridad de subprocesos, si está ejecutando Java 5, considere usar ConcurrentHashMap en Java.

Noche0
fuente
ConcurrentHashMap no está sincronizado de lectura, mientras que Hashtable sí. Entonces, si tiene una gran cantidad de operaciones de lectura que ocurren simultáneamente con las escrituras, un Hashtable le serviría mejor si le preocupa la integridad de los datos.
IgorGanapolsky
5

HashMap y Hashtable se usan para almacenar datos en forma de clave y valor. Ambos utilizan la técnica de hashing para almacenar claves únicas. Sin embargo, hay muchas diferencias entre las clases HashMap y Hashtable que se dan a continuación.

ingrese la descripción de la imagen aquí

Dic
fuente
Bonito resumen visual!
Nadjib Mami el