¿Cuáles son las diferencias entre HashMap y Hashtable en Java?

¿Cuáles son las diferencias entre un HashMap y Hashtable en Java?

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

preguntado el 02 de septiembre de 08 a las 18:09

HashTable está obsoleto en Java 1.7 y se recomienda utilizar la implementación de ConcurrentMap -

@MissFiona No, ConcurrentMap is no necesario aquí, ya que la Pregunta dice "aplicaciones sin subprocesos", lo que significa que el subproceso / concurrencia no es un problema. -

30 Respuestas

Hay varias diferencias entre HashMap y Hashtable en Java:

  1. Hashtable is Sincronizado, mientras que HashMap no es. Esto hace HashMap mejor para aplicaciones sin subprocesos, ya que los objetos no sincronizados suelen funcionar mejor que los sincronizados.

  2. Hashtable no permite null claves o valores. HashMap permite uno null clave y cualquier número de null valores.

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

Dado que la sincronización no es un problema para usted, le recomiendo HashMap. Si la sincronización se convierte en un problema, también puede consultar ConcurrentHashMap.

Respondido el 13 de Septiembre de 18 a las 20:09

Si desea hacer un HashMap seguro para subprocesos, use Collections.synchronizedMap(). - Rok Strniša

También quisiera comentar que el enfoque ingenuo de la seguridad de subprocesos en Hashtable ("sincronizar cada método debería solucionar cualquier problema de concurrencia!") hace que sea mucho peor para aplicaciones roscadas. Es mejor sincronizar externamente un HashMap (y pensando en las consecuencias), o usando un ConcurrentMap implementación (y aprovechando su API extendida para simultaneidad). En pocas palabras: la única razón para usar Hashtable es cuando una API heredada (de aproximadamente 1996) lo requiere. - erickson

HashMap le da flexibilidad al programador para escribir código threadSafe cuando realmente lo usa. Rara vez 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 para subprocesos. - Gaurava Agarval

Hashtable está obsoleto y estamos usando HashMap para entornos no seguros para subprocesos. Si necesita seguridad para subprocesos, puede usar Collections.synchronizedMap () o usar ConcurrentHashMap, que es más eficiente que la tabla hash. - maneesh kumar

Es obsoleto pero no obsoleto y me pregunto por qué. Supongo que eliminar esta clase (y Vector por las mismas razones) rompería demasiado código existente y anotar con @Deprecated implicaría la intención de eliminar el código, que aparentemente no está allí. - Jilles van Gurp

Tenga en cuenta que muchas de las respuestas indican que Hashtable está sincronizado. En la práctica, esto le compra muy poco. La sincronización en los métodos de acceso / mutador detendrá la adición o eliminación de dos subprocesos del mapa simultáneamente, pero en el mundo real a menudo necesitará sincronización adicional.

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

Equivalentemente sincronizado HashMap puede ser obtenido por:

Collections.synchronizedMap(myMap);

Pero para implementar correctamente esta lógica necesitas sincronización adicional de la forma:

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

Incluso iterando sobre un Hashtableentradas (o un HashMap obtenido por Collections.synchronizedMap) no es seguro para subprocesos a menos que también proteja el Map de ser modificado a través de una sincronización adicional.

Implementaciones del ConcurrentMap interfaz (por ejemplo ConcurrentHashMap) resuelve algo de esto incluyendo semántica de verificación-luego-acción segura para subprocesos como:

ConcurrentMap.putIfAbsent(key, value);

respondido 06 mar '19, 12:03

También tenga en cuenta que si se modifica un HashMap, los iteradores que apuntan a él se vuelven inválidos. - Chris K

Entonces, ¿hay alguna diferencia entre sincronizado (myMap) {...} y ConcurrentHashMap en términos de seguridad para subprocesos? - telebog

Muy cierto, traté de explicar lo mismo aquí ..lovehasija.com/2012/08/16/… - Amor hasija

@Bhushan: Se lanzará sobre la base del mejor esfuerzo, este no es un comportamiento garantizado: docs.oracle.com/javase/7/docs/api/java/util/HashMap.html - Matt Stephenson

Habiendo 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 poco fiable. Recibimos varias quejas de fallas dentro de HashMap (y por lo tanto "obviamente" un error de JDK / JVM), cuando la causa era una modificación concurrente. - Lamidas calientes

Hashtable se considera código heredado. No hay nada sobre Hashtable eso no se puede hacer usando HashMap o derivaciones de HashMap, por lo que para el nuevo código, no veo ninguna justificación para volver a Hashtable.

Respondido 07 ago 18, 13:08

De Hashtable javadoc (énfasis agregado): "A partir de la plataforma Java 2 v1.2, esta clase se actualizó para implementar la interfaz Map, haciéndolo 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 que Vector es una versión heredada de Collections.synchronizedList (ArrayList).) - Kip

@ aberrant80: desafortunadamente no tiene opción entre los dos y tiene que usar Hashtable al programar para J2ME ... - por favor

esta respuesta debe eliminarse. contiene información incorrecta y tiene muchos votos a favor. - anon58192932

@ anon58192932 ¿Es posible editar la pregunta para solucionarlo? - GC_

Tenemos que llamar la atención del cartel @ aberrant80 o de un administrador marcando. Marcar podría ayudar, lo intentaré ahora. - anon58192932

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

  1. La HashMap clase es aproximadamente equivalente a Hashtable, excepto que no está sincronizado y permite nulos. (HashMap permite valores nulos como clave y valor, mientras que Hashtable no permite nulls).
  2. HashMap no garantiza que el orden del mapa se mantenga constante en el tiempo.
  3. HashMap no está sincronizado mientras que Hashtable está sincronizado.
  4. Iterador en el HashMap es a prueba de fallos mientras que el enumerador de la Hashtable no es y tira ConcurrentModificationException si cualquier otro hilo modifica el mapa estructuralmente agregando o quitando cualquier elemento excepto Iteratorpropia 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 hilo puede modificar una tabla hash en un momento determinado. Básicamente, significa que cualquier hilo antes de realizar una actualización en un Hashtable tendrá que adquirir un bloqueo en el objeto mientras que otros esperarán a que se libere el bloqueo.
  2. Fail-safe es relevante en el 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 subprocesos invoquen set método ya que no modifica la colección "estructuralmente". Sin embargo, si antes de llamar set, la colección ha sido modificada estructuralmente, IllegalArgumentException será arrojado
  3. La modificación estructural significa eliminar o insertar elementos que podrían cambiar efectivamente la estructura del mapa.

HashMap puede ser sincronizado por

Map m = Collections.synchronizeMap(hashMap);

Map 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 explica más adelante en esta sección. Map le permite iterar sobre claves, valores o pares clave-valor; Hashtable no proporciona la tercera opción. Map proporciona una forma segura de eliminar entradas en medio de la iteración; Hashtable No. Finalmente, Map corrige una deficiencia menor en el Hashtable de la interfaz del. Hashtable tiene un método llamado contiene, que devuelve verdadero si el Hashtable contiene un valor dado. Dado su nombre, esperaría que este método devuelva verdadero si el Hashtable contenía una clave determinada, porque la clave es el mecanismo de acceso principal para un Hashtable. La interfaz del mapa elimina esta fuente de confusión al cambiar el nombre del método containsValue. Además, esto mejora la consistencia de la interfaz: containsValue paralelas containsKey.

La interfaz del mapa

respondido 22 nov., 19:17

Esta respuesta contiene al menos 2 inexactitudes fácticas significativas. Ciertamente NO merece tantos votos a favor. - Stephen C

1) Los iteradores de HashMap NO son a prueba de fallas. Son rápidos en fallar. Hay una gran diferencia de significado entre esos dos términos. 2) No hay set operación en un HashMap. 3) El put(...) la operación no arrojará IllegalArgumentException si hubo un cambio previo. 4) El comportamiento a prueba de fallos de HashMap Además, ocurre si cambia un mapeo. 5) El comportamiento a prueba de fallas is garantizado. (Lo que no está garantizado es el comportamiento de un HashTable si realiza una modificación simultánea. El comportamiento real es ... impredecible.) - Stephen C

6) Hashtable tampoco garantiza que el orden de los elementos del mapa sea estable a lo largo del tiempo. (Quizás estés confundiendo Hashtable con LinkedHashMap.) - Stephen C

¿Alguien más está realmente preocupado de que los estudiantes de estos días tengan la idea errada 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); que la mayoría de las veces toma por sorpresa a los novatos por estar completamente desprotegidos, especialmente si el get() y set() son métodos sincronizados. Muchos de ellos esperan magia. - usuario4229245

Los iteradores en HashMap no son a prueba de fallas - Abdul

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

En serio, es mejor que te mantengas alejado de Hashtable en total. Para las aplicaciones de un solo subproceso, no necesita la sobrecarga adicional de sincronización. Para aplicaciones muy concurrentes, la sincronización paranoica puede provocar inanición, interbloqueos o pausas innecesarias en la recolección de basura. Como señaló Tim Howland, podría usar ConcurrentHashMap preferiblemente.

Respondido el 04 de diciembre de 17 a las 21:12

De hecho, esto tiene sentido. ConcurrentHashMaps le brinda libertad de sincronización y la depuración es mucho más fácil. - prap19

¿Es esto específico de Java o de toda la implementación del mapa hash? - usuario6552957

Tenga en cuenta que HashTable era una clase heredada antes de que se introdujera el marco de colecciones de Java (JCF) y luego se modernizó para implementar el Map interfaz. Así fue Vector y Stack.

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

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

enter image description here

Respondido el 03 de junio de 15 a las 06:06

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

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

mapa hash

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

Tabla de picadillo

  1. Hashtable está 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. Enumerador en Hashtable no es rápido.
  8. Hashtable hereda la clase Diccionario.

Seguí leyendo ¿Cuál es la diferencia entre HashMap y Hashtable en Java?

enter image description here

Respondido 16 ago 18, 13:08

Prácticamente cubierto en esta respuesta (duplicado de): stackoverflow.com/a/39785829/432903. - oracionagupd

¿Por qué dices ~ "Hashtable es una clase heredada¿Dónde está la documentación de respaldo para eso? IgorGanapolsky

@IgorGanapolsky puede leer esto - stackoverflow.com/questions/21086307/… - viajeroraiz

Mantener HashMap es costoso que TreeMap. Porque HashMap crea depósitos adicionales innecesarios. - Abdul

Un LinkedHashMap tiene una lista de entradas doblemente enlazadas, no de depósitos. Se puede acceder a los depósitos a través de índices de matriz y no es necesario vincularlos. - thomas.schuerger

Además de lo que dijo izb, HashMap permite valores nulos, mientras que Hashtable no.

También tenga en cuenta que Hashtable extiende el Dictionary clase, que como el Javadocs estado, es obsoleto y ha sido reemplazado por el Map de la interfaz del.

Respondido el 02 de Septiembre de 08 a las 21:09

pero eso no hace que la HashTable sea obsoleta, ¿verdad? - marcapasos

@Pacerier HashTable está obsoleto desde Java 1.7. - Majid Alí Khan

Eche un vistazo a esta tabla. Proporciona comparaciones entre diferentes estructuras de datos junto con HashMap y Hashtable. La comparación es precisa, clara y fácil de entender.

Matriz de recopilación de Java

respondido 22 nov., 19:17

Hashtable es similar a la HashMap y tiene una interfaz similar. Se recomienda que utilice HashMap, a menos que necesite soporte para aplicaciones heredadas o necesite sincronización, ya que el Hashtables los métodos están sincronizados. Entonces, en su caso, ya que no es un subproceso múltiple, HashMaps son tu mejor apuesta

respondido 02 mar '15, 08:03

Otra diferencia clave entre hashtable y hashmap es que Iterator en HashMap es rápido en fallas mientras que el enumerador para Hashtable no lo es y lanza ConcurrentModificationException si cualquier otro Thread modifica el mapa estructuralmente agregando o quitando cualquier elemento excepto el método remove () del propio 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

Respondido el 08 de Septiembre de 11 a las 07:09

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 antiguo 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 que seremos capaces de construir y acceder a HashMaps como en los viejos lenguajes de scripting:

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

Actualizar: No, no aterrizarán en 1.8 ... :(

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

contestado el 23 de mayo de 17 a las 13:05

Hashtable está sincronizado, mientras que HashMap no lo es. Lo que hace Hashtable más lento que Hashmap.

Para aplicaciones de un solo hilo, use HashMap ya que por lo demás son iguales en términos de funcionalidad.

Respondido el 15 de Septiembre de 20 a las 21:09

  • Tabla de picadillo está sincronizado, si lo está usando en un solo hilo, puede usar mapa hash, que es una versión no sincronizada. Los objetos no sincronizados suelen ser un poco más eficaces. 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 un objeto no nulo como clave o como valor. HashMap puede contener una clave nula y valores nulos.

  • Los iteradores devueltos por Map son rápidos, 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 de eliminación del iterador, el iterador arrojará un ConcurrentModificationException. Por lo tanto, frente a la modificación concurrente, el iterador falla rápida y limpiamente, en lugar de arriesgarse a un comportamiento arbitrario y no determinista en un momento indeterminado en el futuro. Mientras las enumeraciones devueltas por las claves y los métodos de elementos de Hashtable no son rápidas.

  • HashTable y HashMap son miembros de Marco de colecciones de Java (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 usar ConcurrentHashMapConcurrentHashMap en lugar de Hashtable si se desea una implementación altamente concurrente segura para subprocesos.

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

Respondido 29 Abr '12, 14:04

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

Aparte de las diferencias obvias discutidas extensamente en esta pregunta, veo el Hashtable como un auto de "conducción manual" donde tienes un mejor control sobre el hash y el HashMap como la contraparte de "conducción automática" que generalmente funcionará bien.

Respondido el 24 de enero de 14 a las 08:01

Basado en la información aquí, Recomiendo ir con HashMap. Creo que la mayor ventaja es que Java evitará que lo modifique mientras lo está iterando, a menos que lo haga a través del iterador.

Respondido el 02 de Septiembre de 08 a las 21:09

En realidad, no lo previene, solo lo detecta y arroja un error. - Bart van Heukelom

Estoy bastante seguro de que arrojará una ConncurrentModificationException antes de que se modifique la colección subyacente, aunque podría estar equivocado. - comprando

Va a intento para detectar modificaciones concurrentes y lanzar una excepción. Pero si está haciendo algo con hilos, no puede hacer ninguna promesa. Puede suceder absolutamente cualquier cosa, incluso rotura. - chao

A Collection - a veces llamado contenedor - es simplemente un objeto que agrupa varios elementos en una sola unidad. CollectionLos correos electrónicos se utilizan para almacenar, recuperar, manipular y comunicar datos agregados. Un marco de colecciones W es una arquitectura unificada para representar y manipular colecciones.

La HashMap JDK1.2 y Hashtable JDK1.0, ambos se utilizan para representar un grupo de objetos que se representan en <Key, Value> par. Cada <Key, Value> par se llama Entry objeto. La colección de Entradas está referida por el objeto de HashMap y Hashtable. Las claves de una colección deben ser únicas o distintivas. [ya que se utilizan para recuperar un valor asignado a una clave en particular. los valores de 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 Dictionary. De JDK1.2 Hashtable está rediseñado para implementar el Interfaz de mapa para hacer un miembro del marco de la colecció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 la cantidad 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 "hash collision", un solo depósito almacena múltiples entradas, que deben buscarse secuencialmente. El factor de carga es una medida de qué tan llena se permite que se llene 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 factor de carga / relación de llenado (0.75).

Hash Map y Hashtable

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

HashMap, Hashtable en caso de colisiones hash, almacenan las entradas del mapa en listas vinculadas. Desde Java8 para HashMap si el depósito de hash crece más allá de un cierto umbral, ese depósito cambiará de linked list of entries to a balanced tree. que mejoran el desempeño en el peor de los casos de O (n) a O (log n). Al convertir la lista en árbol binario, el código hash se utiliza como variable de ramificación. Si hay dos códigos hash diferentes en el mismo depósito, 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, HashMap asume que las claves son comparables y compara la clave para determinar la dirección de modo que se pueda mantener cierto orden. Es una buena práctica hacer las claves de HashMap comparable. Al agregar entradas si el tamaño del depósito alcanza TREEIFY_THRESHOLD = 8 convertir la lista enlazada de entradas en un árbol equilibrado, al eliminar entradas de menos de TREEIFY_THRESHOLD y como mucho UNTREEIFY_THRESHOLD = 6 reconvertirá el árbol equilibrado en una lista de entradas enlazadas. Java 8 SRC, poste de la pila

« Iteració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      |
    +--------------------+-----------+-------------+

Iterator es de naturaleza a prueba de fallas. es decir, arroja ConcurrentModificationException si una colección se modifica mientras se itera en otro método que no sea remove (). Mientras que Enumeration es de naturaleza a prueba de fallas. No arroja ninguna excepción si se modifica una colección durante la iteración.

Según Java API Docs, Iterator siempre se prefiere a la Enumeration.

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

In Java 5 introdujo la interfaz ConcurrentMap: ConcurrentHashMap - un altamente concurrente, de alto rendimiento ConcurrentMap implementación respaldada por una tabla hash. Esta implementación nunca se bloquea cuando se realizan recuperaciones y permite al cliente seleccionar el nivel de simultaneidad para las actualizaciones. Está diseñado como un reemplazo directo para Hashtable: además de implementar ConcurrentMap, admite todos los métodos "heredados" propios de Hashtable.

  • Cada HashMapEntrys valor es volátiles asegurando así una consistencia de grano fino para modificaciones contenidas y lecturas posteriores; cada lectura refleja la actualización completada más recientemente

  • Los iteradores y 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 Hashtable pero a diferencia HashMap, esta clase no permite que se utilice 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

HashMap permite un máximo de una clave nula y cualquier número de valores nulos. Mientras que Hashtable no permite ni siquiera una clave nula y un valor nulo, si la clave o el valor es nulo, arroja NullPointerException. Ejemplo

« Sincronizado, seguro para subprocesos

Hashtable está sincronizado internamente. Por lo tanto, es muy seguro de usar. Hashtable en aplicaciones de subprocesos múltiples. Mientras que HashMap no está sincronizado internamente. Por lo tanto, no es seguro usar HashMap en aplicaciones multiproceso sin sincronización externa. Puede sincronizar externamente HashMap usar Collections.synchronizedMap() método.

« Rendimiento

As Hashtable está sincronizado internamente, esto hace Hashtable un poco más lento que el HashMap.


@Ver

Respondido el 20 de junio de 20 a las 10:06

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

Respondido el 02 de Septiembre de 08 a las 23:09

1.Hashmap y HashTable ambos almacenan la clave y el valor.

2.Hashmap puede almacenar una clave como null. Hashtable no puedo almacenar null.

3.HashMap no está sincronizado pero Hashtable está sincronizado.

4.HashMap se puede sincronizar con Collection.SyncronizedMap(map)

Map hashmap = new HashMap();

Map map = Collections.SyncronizedMap(hashmap);

respondido 22 mar '15, 15:03

Aparte de las diferencias ya mencionadas, cabe señalar que desde Java 8, HashMap reemplaza dinámicamente los nodos (lista enlazada) utilizados en cada depósito con TreeNodes (árbol rojo-negro), de modo que incluso si existen colisiones de alto hash, el peor de los casos al buscar is

O (log (n)) para HashMap Vs O (n) en Hashtable.

* La mejora mencionada no se ha aplicado a Hashtable todavía, pero solo para HashMap, LinkedHashMapy ConcurrentHashMap.

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 cambio de tamaño), el árbol se convierte de nuevo a la lista vinculada.

contestado el 04 de mayo de 16 a las 16:05

Hay 5 diferenciaciones básicas con HashTable y HashMaps.

  1. Maps le permite iterar y recuperar claves, valores y ambos pares clave-valor también, donde HashTable no tiene toda esta capacidad.
  2. En Hashtable hay una función contiene (), que es muy confuso de usar. Porque el significado de contiene se desvía ligeramente. ¿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 puede eliminar elementos mientras itera, de forma segura. donde ya que no es posible en tablas hash.
  4. Las tablas hash están sincronizadas de forma predeterminada, por lo que se pueden usar con varios subprocesos fácilmente. Mientras que los HashMaps no se sincronizan de forma predeterminada, se pueden usar con un solo hilo. Pero aún puede convertir HashMap en sincronizado utilizando la función synchronizedMap (Map m) de la clase util de Colecciones.
  5. HashTable no permitirá claves nulas ni valores nulos. Donde como HashMap permite una clave nula y múltiples valores nulos.

Respondido 10 Abr '14, 16:04

Mi pequeña contribución:

  1. Primera y más significativa diferencia entre Hashtable y HashMap es eso, HashMap no es seguro para subprocesos mientras Hashtable es una colección segura para subprocesos.

  2. Segunda diferencia importante entre Hashtable y HashMap es el rendimiento, ya que HashMap no está sincronizado funciona mejor que Hashtable.

  3. Tercera diferencia en Hashtable vs HashMap es que Hashtable es una clase obsoleta y deberías estar usando ConcurrentHashMap en lugar de Hashtable en Java

Respondido el 20 de junio de 20 a las 10:06

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 la colección.

Respondido el 28 de diciembre de 18 a las 02:12

Si es así, debería ser en los comentarios, no como respuesta. - manikant gautam

Tabla de picadillo es una clase heredada en el jdk que ya no debería usarse. Reemplace sus usos con ConcurrentHashMapConcurrentHashMap. Si no necesita seguridad para subprocesos, utilice mapa hash que no es a salvo de amenazas pero más rápido y usa menos memoria.

Respondido 21 Abr '13, 18:04

Porque pensé que las otras respuestas, en ese momento, no descartaron HashTable, pero explicaron que era seguro para subprocesos. La verdad es que tan pronto como vea HashTable en el código, debe reemplazarlo con ConcurrentHashMap sin perder el ritmo. Y si la seguridad de los subprocesos no es una preocupación, HashMap se puede utilizar para mejorar un poco el rendimiento. - Jontejj

  1. Hashtable está sincronizado mientras que HashMap no es.
  2. Otra diferencia es que el iterador en el HashMap es a prueba de fallos mientras que el enumerador de la Hashtable no lo es. Si cambia el mapa mientras itera, lo sabrá.
  3. HashMap permite valores nulos en él, mientras que Hashtable no lo hace

Respondido 16 ago 19, 20:08

El iterador HashMap es a prueba de fallas, no a prueba de fallas. Es por eso que tenemos ConcurrentHashMap que permite la modificación durante la iteración. Revisa esta publicación journaldev.com/122/… - Pankaj

@Pankaj Exactamente. - Gaurav

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 hash. por lo que 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 tiene un mejor 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.

Respondido 25 Jul 17, 15:07

Votado en contra porque esta respuesta no es correcta en algunos aspectos. Hashtable no implementa la interfaz Map, solo extiende la clase Dictionary, que está obsoleta. - Ioannis Sermetziadis

Hashtable:

Tabla de picadillo es una estructura de datos que conserva los valores del par clave-valor. No permite nulos tanto para las claves como para los valores. Obtendrás un NullPointerException si agrega un valor nulo. Está sincronizado. Entonces viene con su costo. Solo un hilo puede acceder Tabla de picadillo en un momento determinado.

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

    }
}

Mapa hash:

mapa hash es como Tabla de picadillo pero también acepta pares clave-valor. Permite nulos tanto para las claves como para los valores. Su rendimiento mejor es mejor que HashTable, porque es unsynchronized.

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

    }
}

Respondido 26 Abr '16, 10:04

mapa hash y Tabla de picadillo ambos se utilizan para almacenar datos en forma de clave y valor. Ambos utilizan la técnica de hash para almacenar claves únicas. Pero hay muchas diferencias entre las clases HashMap y Hashtable que se detallan a continuación.

enter image description here

Respondido 30 Oct 19, 11:10

HashMap se emula y, por lo tanto, se puede utilizar en GWT client code mientras Hashtable no es.

Respondido 15 Jul 13, 10:07

¿Es esa una descripción completa de las diferencias entre las dos apis? - IgorGanapolsky

Sí (¡sic!). Eso es todo lo que los desarrolladores de GWT necesitan saber al respecto. - pong

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 principales diferencias entre HashMap y Hashtable

HashMap y Hashtable implementan la interfaz java.util.Map, pero hay algunas diferencias que los desarrolladores de Java deben comprender para escribir un 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 del 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 la 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 hilo puede modificar una tabla hash en un momento dado. Básicamente, significa que cualquier hilo 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 aproximadamente 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 vs Hashtable es que Iterator en HashMap es un iterador a prueba de fallas, mientras que el enumerador para Hashtable no lo es y lanza ConcurrentModificationException si cualquier otro Thread modifica el mapa estructuralmente agregando o eliminando cualquier elemento excepto la eliminación del propio Iterator ( ) método. Pero este no es un comportamiento garantizado y JVM lo hará con el mejor esfuerzo posible. Esta también es una diferencia importante entre Enumeration e Iterator en Java.

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

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

Tenga en cuenta que HashMap se puede sincronizar mediante

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 base a eso, solo use Hashtable si es absolutamente necesario seguridad para subprocesos, si está ejecutando Java 5, considere usar ConcurrentHashMap en Java.

Respondido 06 ago 15, 09:08

ConcurrentHashMap no está sincronizado con lectura, mientras que Hashtable sí lo está. Entonces, si tiene una gran cantidad de operaciones de lectura que ocurren simultáneamente con escrituras, una Hashtable le resultará más útil si se preocupa por la integridad de los datos. - IgorGanapolsky

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.