¿Es posible HashMap
devolver un valor predeterminado para todas las claves que no se encuentran en el conjunto?
java
dictionary
hashmap
Larry
fuente
fuente
getOrDefault()
enlaceRespuestas:
[Actualizar]
Como lo señalaron otras respuestas y comentaristas, a partir de Java 8 simplemente puede llamar
Map#getOrDefault(...)
.[Original]
No hay una implementación de Map que haga esto exactamente, pero sería trivial implementar la suya propia extendiendo HashMap:
fuente
(v == null)
a(v == null && !this.containsKey(k))
en caso de que agreguen unnull
valor a propósito . Lo sé, este es solo un caso de esquina, pero el autor puede encontrarse con él.!this.containsValue(null)
. Esto es sutilmente diferente de!this.containsKey(k)
. LacontainsValue
solución fallará si a alguna otra clave se le ha asignado explícitamente un valor denull
. Por ejemplo:map = new HashMap(); map.put(k1, null); V v = map.get(k2);
en este caso,v
seguirá siendonull
, ¿correcto?En Java 8, use Map.getOrDefault . Se necesita la clave y el valor para devolver si no se encuentra una clave coincidente.
fuente
getOrDefault
es muy agradable, pero requiere la definición predeterminada cada vez que se accede al mapa. Definir un valor predeterminado una vez también tendría beneficios de legibilidad al crear un mapa estático de valores.private static String get(Map map, String s) { return map.getOrDefault(s, "Error"); }
Use el Mapa predeterminado de Commons si no tiene ganas de reinventar la rueda, por ejemplo,
También puede pasar un mapa existente si no está a cargo de crear el mapa en primer lugar.
fuente
Java 8 introdujo un buen método predeterminado computeIfAbsent para la
Map
interfaz que almacena el valor calculado de manera diferida y no rompe el contrato del mapa:Origen: http://blog.javabien.net/2014/02/20/loadingcache-in-java-8-without-guava/
Descargo de responsabilidad: esta respuesta no coincide exactamente con lo que OP solicitó, pero puede ser útil en algunos casos coincidir con el título de la pregunta cuando el número de claves es limitado y el almacenamiento en caché de diferentes valores sería rentable. No debe usarse en caso contrario con muchas teclas y el mismo valor predeterminado, ya que esto innecesariamente desperdiciaría memoria.
fuente
¿No puedes crear un método estático que haga exactamente esto?
fuente
Simplemente puede crear una nueva clase que herede HashMap y agregar el método getDefault. Aquí hay un código de muestra:
Creo que no debe anular el método get (clave K) en su implementación, debido a las razones especificadas por Ed Staub en su comentario y porque romperá el contrato de la interfaz de Map (esto puede conducir a algunos problemas difíciles de encontrar loco).
fuente
get
método. Por otro lado, su solución no permite usar la clase a través de la interfaz, que a menudo puede ser el caso.Utilizar:
fuente
Hace esto por defecto. Vuelve
null
.fuente
HashMap
solo por esta funcionalidad cuandonull
está perfectamente bien.NullObject
embargo, no está bien si está utilizando un patrón o si no desea dispersar las verificaciones nulas en todo el código, un deseo que entiendo completamente.En java 8+
fuente
El LazyMap me pareció bastante útil.
Esto le permite hacer algo como esto:
La llamada a
get
crea un valor predeterminado para la clave dada. Usted especifica cómo crear el valor predeterminado con el argumento de fábrica paraLazyMap.lazyMap(map, factory)
. En el ejemplo anterior, el mapa se inicializa a un nuevoAtomicInteger
con valor 0.fuente
List<String>
? Al usar la respuesta aceptada, me arriesgaría a usar la misma lista para cada nueva clave, en lugar de (por ejemplo) unanew ArrayList<String>()
de fábrica.No directamente, pero puede extender la clase para modificar su método get. Aquí hay un ejemplo listo para usar: http://www.java2s.com/Code/Java/Collections-Data-Structure/ExtendedVersionofjavautilHashMapthatprovidesanextendedgetmethodaccpetingadefaultvalue.htm
fuente
Ejemplo de uso:
fuente
Necesitaba leer los resultados devueltos por un servidor en JSON donde no podía garantizar que los campos estuvieran presentes. Estoy usando la clase org.json.simple.JSONObject que se deriva de HashMap. Aquí hay algunas funciones auxiliares que empleé:
fuente
En proyectos mixtos de Java / Kotlin, también considere Kotlin's Map.withDefault .
fuente