Diferencias entre HashMap y Hashtable

1. Información general

En este breve tutorial, nos centraremos en las diferencias centrales entre Hashtable y HashMap .

2. Hashtable y HashMap en Java

Hashtable y HashMap son bastante similares: ambas son colecciones que implementan la interfaz Map .

Además, los métodos put () , get () , remove () y containsKey () proporcionan un rendimiento de tiempo constante O (1). Internamente, estos métodos funcionan basándose en un concepto general de hash que utiliza cubos para almacenar datos.

Ninguna clase mantiene el orden de inserción de los elementos. En otras palabras, el primer elemento agregado puede no ser el primer elemento cuando iteramos sobre los valores.

Pero también tienen algunas diferencias que hacen que uno sea mejor que otro en algunas situaciones. Miremos más de cerca estas diferencias.

3. Diferencias entre Hashtable y HashMap

3.1. Sincronización

En primer lugar, Hashtable es seguro para subprocesos y se puede compartir entre varios subprocesos en la aplicación.

Por otro lado, HashMap no está sincronizado y varios subprocesos no pueden acceder a él sin un código de sincronización adicional. Podemos usar Collections.synchronizedMap () para hacer una versión segura para subprocesos de un HashMap . También podemos simplemente crear un código de bloqueo personalizado o hacer que el código sea seguro para subprocesos utilizando la palabra clave sincronizada .

HashMap no está sincronizado, por lo tanto, es más rápido y usa menos memoria que Hashtable . Generalmente, los objetos no sincronizados son más rápidos que los sincronizados en una aplicación de un solo subproceso.

3.2. Valores nulos

Otra diferencia es el manejo nulo . HashMap permite agregar una entrada con nulo como clave, así como muchas entradas con nulo como valor. Por el contrario, Hashtable no permite nulos en absoluto . Veamos un ejemplo de null y HashMap :

HashMap map = new HashMap(); map.put(null, "value"); map.put("key1", null); map.put("key2", null);

Esto resultará en:

assertEquals(3, map.size());

A continuación, veamos en qué se diferencia Hashtable:

Hashtable table = new Hashtable(); table.put("key", null);

Esto da como resultado una NullPointerException . Agregar un objeto con null como clave también da como resultado una NullPointerException :

table.put(null, "value");

3.3. Iteración sobre elementos

HashMap usa Iterator para iterar sobre los valores, mientras que Hashtable tiene Enumerator para el mismo. El Iterador es un sucesor de Enumerator que elimina sus pocos inconvenientes. Por ejemplo, Iterator tiene un método remove () para eliminar elementos de colecciones subyacentes.

El iterador es un iterador a prueba de fallas. En otras palabras, lanza una ConcurrentModificationException cuando la colección subyacente se modifica durante la iteración. Veamos el ejemplo de fail-fast:

HashMap map = new HashMap(); map.put("key1", "value1"); map.put("key2", "value2"); Iterator iterator = map.keySet().iterator(); while(iterator.hasNext()){ iterator.next(); map.put("key4", "value4"); }

Esto arroja una excepción ConcurrentModificationException porque estamos llamando a put () mientras iteramos sobre la colección.

4. Cuándo elegir HashMap sobre Hashtable

Deberíamos usar HashMap para una aplicación no sincronizada o de un solo subproceso.

Vale la pena mencionar que desde JDK 1.8, Hashtable ha quedado obsoleto. Sin embargo, ConcurrentHashMap es un excelente reemplazo de Hashtable . Deberíamos considerar ConcurrentHashMap para usar en aplicaciones con múltiples subprocesos.

5. Conclusión

En este artículo, ilustramos las diferencias entre HashMap y Hashtable y lo que debemos tener en cuenta cuando debemos elegir uno.

Como de costumbre, la implementación de todos estos ejemplos y fragmentos de código ha terminado en Github.