2010-05-31 23 views
73

HashMap permite una clave nula y cualquier cantidad de valores nulos. ¿Cuál es el uso de ello?¿Para qué sirve agregar una clave o valor nulo a un HashMap en Java?

+11

"Quizás el problema no es que nada nos moleste, sino que lo estamos molestando". – bmargulies

+3

En Guava, google collections, muchas clases no permiten nulos y el razonamiento detrás de esto es que el 95% de los casos no necesitan nulo y pueden representar errores, que pueden ser difíciles de encontrar. – stivlo

+0

Lo extraño es que 'ConcurrentHashMap' no admite claves nulas, mientras que' HashMap' sí lo hace. – codepleb

Respuesta

106

No estoy seguro de lo que está preguntando, pero si está buscando un ejemplo de cuándo uno quisiera usar una clave nula, los uso a menudo en los mapas para representar el caso predeterminado (es decir, el valor que se debe utilizar si una clave determinada no está presente):

Map<A, B> foo; 
A search; 
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null); 

HashMap maneja claves nulas de manera especial (ya que no puede llamar .hashCode() en un objeto nulo), pero los valores nulos no son nada especial, se almacenan en el mapa como cualquier otra cosa

+3

Entonces, si .hashCode() no es posible en null, ¿quién decide en qué carro entrará la clave nula? – Pacerier

+22

@Pacerier Hay un método especial en 'HashMap' (' putForNullKey') que lo maneja; lo almacena en la tabla 0 –

+0

@MichaelMrozek su última línea 'B val = foo.containsKey (search)? foo.get (búsqueda): foo.get (null); ' Creo que simplemente podemos llamar al método get en la clave de búsqueda que tendrá el mismo resultado. 'B val = foo.get (búsqueda);' ¿podría corregirme si me sale algo mal? – dheerajraaj

25

Un ejemplo sería para modelar árboles. Si está utilizando un HashMap para representar una estructura de árbol, donde la clave es la primaria y el valor es la lista de elementos secundarios, los valores para la clave null serían los nodos raíz.

2

Aquí está mi ejemplo solamente-algo-artificiosa de un caso en el que la clave null puede ser útil:

public class Timer { 
    private static final Logger LOG = Logger.getLogger(Timer.class); 
    private static final Map<String, Long> START_TIMES = new HashMap<String, Long>(); 

    public static synchronized void start() { 
     long now = System.currentTimeMillis(); 
     if (START_TIMES.containsKey(null)) { 
      LOG.warn("Anonymous timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(null).longValue()) +"ms"); 
     } 
     START_TIMES.put(null, now); 
    } 

    public static synchronized long stop() { 
     if (! START_TIMES.containsKey(null)) { 
      return 0; 
     } 

     return printTimer("Anonymous", START_TIMES.remove(null), System.currentTimeMillis()); 
    } 

    public static synchronized void start(String name) { 
     long now = System.currentTimeMillis(); 
     if (START_TIMES.containsKey(name)) { 
      LOG.warn(name + " timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(name).longValue()) +"ms"); 
     } 
     START_TIMES.put(name, now); 
    } 

    public static synchronized long stop(String name) { 
     if (! START_TIMES.containsKey(name)) { 
      return 0; 
     } 

     return printTimer(name, START_TIMES.remove(name), System.currentTimeMillis()); 
    } 

    private static long printTimer(String name, long start, long end) { 
     LOG.info(name + " timer ran for " + (end - start) + "ms"); 
     return end - start; 
    } 
} 
+0

Si está tratando de detener un temporizador inexistente, o uno que ha sido detenido ya, eso debería ser un error, no ignorado. –

+0

@QPaysTaxes - Depende de tu intento. Si quieres una utilidad liviana que se pueda usar fácilmente, generalmente no quieres 'tirar Excepción'. Además, no es como intentar detener un temporizador que ya no existe o que ya se detuvo, algo de lo que la persona que llama en general puede recuperarse. – aroth

1

Otro ejemplo: Yo lo uso para agrupar datos por fecha. Pero algunos datos no tienen fecha. Puedo agruparlo con el encabezado "NoDate"

3

Las respuestas hasta ahora solo consideran el valor de tener una clave null, pero la pregunta también pregunta acerca de any number of null values.

La ventaja de almacenar el valor null en una clave de un HashMap es la misma que en las bases de datos, etc. Puede registrar una distinción entre tener un valor vacío (por ejemplo, cadena "") y no tener un valor en absoluto (nulo).

6

Un ejemplo de uso para nullvalores es cuando se utiliza un HashMap como una memoria caché para los resultados de una operación costosa (tales como una llamada a un servicio web externo) que puede volver null.

Poner un valor null en el mapa a continuación, le permite distinguir entre el caso en el que la operación no se ha realizado para una clave dada (cache.containsKey(someKey) vuelve false), y donde la operación se ha realizado pero regresó un valor null (cache.containsKey(someKey) devuelve true, cache.get(someKey) devuelve null).

Sin null valores, tendría que poner algún valor especial en la memoria caché para indicar una respuesta null, o simplemente no almacenar esa respuesta en caché y realizar la operación todo el tiempo.

0

Una clave nula también puede ser útil cuando el mapa almacena datos para selecciones de IU donde la clave del mapa representa un campo de frijol.

Un valor de campo nulo correspondiente se representaría, por ejemplo, como "(seleccione)" en la selección de la interfaz de usuario.

Cuestiones relacionadas