utiliza significa sensitive sensible que para minusculas mayusculas ignorar funciona equalsignorecase como java comparator

java - significa - Comparador no sensible a mayúsculas y minúsculas rompe mi TreeMap



para que se utiliza el equalsignorecase (4)

Debe asegurarse de que la igualdad de los elementos de ese mapa sea consistente con el comparador. Citando el comentario de la clase:

Tenga en cuenta que la ordenación mantenida por un mapa de árbol, como cualquier mapa ordenado, y si se proporciona o no un comparador explícito, debe ser consistente con iguales si este mapa ordenado debe implementar correctamente la interfaz.

Un Comparator que utilicé en mi TreeMap rompió el comportamiento que pretendía para ese TreeMap . Mira el siguiente código:

TreeMap<String, String> treeMap = new TreeMap<>(new Comparator<String>() { public int compare(String o1, String o2) { return o1.toLowerCase().compareTo(o2.toLowerCase()); } }); treeMap.put("abc", "Element1"); treeMap.put("ABC", "Element2");

Lo que creo que he hecho es que he creado un mapa que está ordenado por sus claves, sin distinción de mayúsculas y minúsculas. Los dos elementos distintos tienen claves no iguales ( abc y ABC ) cuya comparación devolverá 0 . Esperaba un orden aleatorio de los dos elementos. Sin embargo, el comando:

System.out.println("treeMap: " + treeMap);

resultó en:

treeMap: {abc=Element2}

La clave abc se ha reasignado al valor Element2 !

¿Alguien puede explicar cómo podría suceder esto y si es un comportamiento válido y documentado de TreeMap ?


El Comparator que pasa a un TreeMap determina no solo el orden de las claves dentro del Map , sino que también determina si dos claves se consideran idénticas (se consideran idénticas cuando compare() devuelve 0 ).

Por lo tanto, en su TreeMap , "abc" y "ABC" se consideran claves idénticas. Map no permiten claves idénticas, por lo que el segundo valor Element2 sobrescribe el primer valor Element1 .



Ocurre porque TreeMap considera elementos iguales si a.compareTo(b) == 0 . Está documentado en el JavaDoc para TreeMap (énfasis mío):

Tenga en cuenta que la ordenación mantenida por un mapa de árbol, como cualquier mapa ordenado, y si se proporciona o no un comparador explícito, debe ser consistente con equals si este mapa ordenado implementa correctamente la interfaz del Mapa. (Consulte Comparable o Comparator para una definición precisa de consistente con equals ). Esto se debe a que la interfaz del Mapa se define en términos de la operación de equals , pero un mapa clasificado realiza todas las comparaciones de claves usando su compareTo (o compare ), por lo que dos Las claves que se consideran iguales por este método son , desde el punto de vista del mapa ordenado, iguales . El comportamiento de un mapa ordenado está bien definido incluso si su orden es inconsistente con los equals ; simplemente no cumple con el contrato general de la interfaz del Mapa.

Tu comparador no es consistente con iguales.

Si desea mantener los elementos de caso que no son iguales pero sí que son ignorados, ponga un segundo nivel de verificación en su comparador, para usar el ordenamiento que distingue entre mayúsculas y minúsculas:

public int compare(String o1, String o2) { int cmp = o1.toLowerCase().compareTo(o2.toLowerCase()); if (cmp != 0) return cmp; return o1.compareTo(o2); }