2008-10-17 9 views

Respuesta

60

TreeMap extends Map y admite comparadores personalizados.

String proporciona un comparador predeterminado que no distingue entre mayúsculas y minúsculas.

Así:

final Map<String, ...> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); 

El comparador no toma en cuenta la configuración regional. Lea más sobre esto en su JavaDoc.

+4

Tenga en cuenta que no necesita preocuparse por la configuración regional * si controla las claves que se están utilizando * y no sus usuarios finales, y las claves son en inglés. –

+0

Si necesita un Mapa que permita valores nulos, que TreeMap no admite, intente con CaseInsenstiveMap en https://github.com/jdereg/java-util. Éste accede al Mapa en O (1) a diferencia de TreeMap que es O (log n). –

14

Necesita una clase contenedora para la clave String con inserciones mayúsculas y minúsculas inseridas() y hashCode(). Úselo en lugar de la Cadena para la clave del Mapa.

Ver una implementación de ejemplo en http://www.java.happycodings.com/Java_Util_Package/code3.html Lo encontré en 2 minutos de búsqueda de Google. Me parece sensato, aunque nunca lo he usado.

+0

Un poco complicado, ¿no? No me gusta implementar iguales, y hashCode evita todo, si realmente no es realmente necesario. Prefiero el enfoque de crear una implementación de Map anulando los métodos put y get. –

+1

La creación de una clase contenedora se realiza todo el tiempo y no es nada complicado. La solución de la clase contenedora también es mucho más limpio que el overrider put, get, putAll. Puede usar la clase contenedora en cualquier colección basada en hashes o igual (HashSet, HashMap, ArrayList, etc.) –

+0

La portabilidad entre diferentes colecciones es interesante. Gracias. No pensé al respecto. Supongo que cada enfoque tiene sus ventajas y desventajas. –

42

Puede usar CaseInsensitiveMap de Apache's Commons Collections.

+1

tenga en cuenta que CaseInsensitiveMap [no es genérico] (http://commons.apache.org/proper/commons-collections/javadocs/api-3.2.1/org/apache/commons/collections/map/CaseInsensitiveMap.html), por lo que no puedes hacer 'Map ' con eso. – eis

+4

A partir del lanzamiento 4.0, las Colecciones de Apache Commons son genéricas. –

31

¿Sería posible implementar su propio mapa reemplazando métodos put/get?

public class CaseInsensitiveMap extends HashMap<String, String> { 
    ... 
    put(String key, String value) { 
     super.put(key.toLowerCase(), value); 
    } 

    get(String key) { 
     super.get(key.toLowercase()); 
    } 
} 

Este enfoque no lo obliga a cambiar su tipo de "clave" sino su implementación de Mapa.

+4

Ese es básicamente el enfoque adoptado en las Colecciones de Apache Commons CaseInsensitiveMap. –

+4

Recuerde utilizar una configuración regional al realizar operaciones de mayúsculas y minúsculas. – marcospereira

+3

No olvides anular todos los demás métodos "poner" como putAll. –

3

Las tres soluciones obvias que vienen a la mente:

  • Normalizar el caso antes de utilizar una cadena como una llave (configuración regional turca no funciona de manera diferente del resto del mundo).

  • Utilice un tipo de objeto especial diseñado para ser utilizado como llave. Esta es una expresión común para tratar con claves compuestas.

  • Utilice un TreeMap con un Comparador que no distingue entre mayúsculas y minúsculas (posiblemente una fuerza PRIMARIA o SECUNDARIA java.text.Collator). Desafortunadamente, la biblioteca Java no tiene un equivalente de Comparador para hashCode/equals.

3

Usted podría usar mi licencia Apache CaseInsensitiveMap discuten here. A diferencia de la versión de Apache Commons, conserva el caso de las claves. Implementa el contrato de mapa más estrictamente que TreeMap (además tiene una mejor semántica simultánea) (ver los comentarios del blog para más detalles).

0

Trove4j puede usar hashing personalizado para un HashMap. Sin embargo, esto puede tener implicaciones en el rendimiento dado que los códigos hash no pueden almacenarse en caché (¿aunque Trove4j puede haber encontrado una forma de evitar esto?). Los objetos Wrapper (como los describe John M) no tienen esta deficiencia de almacenamiento en caché. También vea mi otra respuesta con respecto a TreeMap.

0

Compruebe la respuesta aceptada en el siguiente enlace. How to check for key in a Map irrespective of the case?

El fondo es "La solución más sencilla es simplemente convertir todas las entradas a mayúsculas (o en minúsculas) antes de insertar/comprobación. Incluso podría escribir su propio envoltorio mapa que hacer esto para garantizar la coherencia."

Cuestiones relacionadas