Ordenar alfabéticamente cadenas con la clase Collator en Java

Publicado por pico.dev el .
blog-stack java planeta-codigo programacion
Comentarios

Sin usar la clase Collator incluida en el JDK al ordenar alfabéticamente una lista de palabras obtendremos en algún caso un resultado que nos extrañará y seguramente no sea lo que esperamos. La clase String implementa la interfaz Comprable pero esta ordenación es en base al valor del código unicode sin tener en cuenta los diferentes niveles de diferencias que se pueden usar según el Locale y la clase Collator.

Java

Quizá algunos digan que la aparentemente sencilla tarea de ordenar una lista de palabras es algo fácil de hacer con cualquier lenguaje de programación. La realidad es que puede complicarse en una buena cantidad si se ha de realizar con los caracteres del alfabeto de algunos lenguajes. La ordenación no es tan simple como realizar lo siguiente en código Java:

Primeramente nos daremos cuenta de que la siguiente lista de nombres de provincias las ordena de una forma que quizá no es la que esperamos. En algunas páginas web se puede observar este error en algunos elementos de selección de opciones de nombres de paises, ciudades, provincias u otro conjunto de elementos que suelen estar ordenados alfabéticamente para facilitar el encontrar el elemento a seleccionar pero que si se da el caso de que hay variación de palabras con tildes y sin ellas y minúsculas y mayúsculas se presenta la ordenación incorrecta.

Como se observa las palabras con letras mayúsculas se ordenan antes que las palabras con letras en minúscula independientemente de la letra del alfabeto, seguramente esta no es la ordenación deseada. En algunos lenguajes como el español algo similar ocurre con las palabras que llevan tilde en alguna letra. Convertir las palabras a mayúsculas o minúsculas o eliminar las tildes por los mismos sin tilde previamente a hacer la ordenación además de no ser una buena solución no sirve para otros lenguajes con diferentes formas de tilde y marcas en las letras.

En Java la solución es utilizar la clase Collator, esta clase establece varios niveles en las que las letras se consideran diferentes. Por ejemplo, en español las letras e y f se consideran diferencias primarias (diferentes letras), e y é son diferencias secundarias (diferentes tildes) y e y E son diferencias terciarias (diferencias entre mayúsculas y minúsculas). Las diferencias entre caracteres dependen del Locale y un Collator se obtiene en base a él con el método estático getInstance​(Locale). Con el método setStrength(int) se establece el nivel de diferencias deseadas.

Usando la clase Collator y realizando la ordenación de la misma lista anterior el resultado es diferente y seguramente más apropiado. Como la clase Collator implementa la interfaz Comparable podemos usarla como el comparador aplicar en el método Arrays.sort(T[], Comparator<? super T>) o List.sort(Comparator<? super E>).

Utilizando el Collator con solo diferencias primarias Cantabria se ordena al final de la lista por tener las letras a, A y Á una diferencia primaria con C. Con diferencias secundarias las letras A y a se ordenan antes que Á por tener diferencias secundarias. Finalmente, con diferencias terciarias a se ordena antes que A.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew run.