Todos sabemos que usar el método equals() de String para la comparación de igualdad fallará miserablemente. En su lugar, se debe usar Collator, así:¿Dónde puedo encontrar un conjunto específico de reglas de intercalación para la comparación de igualdad de cadenas?
// we need to detect User Interface locale somehow
Locale uiLocale = Locale.forLanguageTag("da-DK");
// Setting up collator object
Collator collator = Collator.getInstance(uiLocale);
collator.setStrength(Collator.SECONDARY);
collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
// strings for equality testing
String test1 = "USA lover Grækenland støtte";
String test2 = "USA lover graekenland støtte";
boolean result = collator.equals(test1, test2);
Ahora, este código funciona, es decir el resultado se da menos UILocale se establece en danés. En tal caso, dará falso. Desde luego, entiendo por qué esto sucedió: esto es sólo porque el método es igual se implementa como esto:
return compare(s1, s2) == Collator.Equal;
Este método llama al que se utiliza para clasificar y comprobar si las cadenas son iguales. No lo son, porque las reglas de intercalación específicas danesas requieren que æ se ordenen después (si entiendo correctamente el resultado del método de comparación) ae. Sin embargo, estas cadenas son realmente lo mismo, con esta resistencia tanto las diferencias de casos como los caracteres de compatibilidad (así se llama) deben tratarse como iguales.
Para solucionar esto, uno usaría RuleBasedCollator con un conjunto específico de reglas que funcionarán para el caso de igualdad.
Finalmente, la pregunta es: ¿alguien sabe dónde puedo obtener tales reglas específicas (no solo para el danés, sino también para otros idiomas), para que los caracteres de compatibilidad, ligaduras, etc. sean tratados como iguales (CLDRchart no parece para contener tal o he fallado en buscarlo)?
O tal vez quiero hacer algo estúpido aquí, y realmente debería usar simplemente UCA para comparación de igualdad (cualquier muestra de código, por favor)?
Cadenas iguales() hace exactamente lo que se supone que debe hacer y comparar palabras con ortografía equivalente en ciertos idiomas no es parte de eso, así que me parece que decir que falla miserablemente es engañoso. – Stefan
@Stefan: El problema es que no lo es. Por ejemplo, para cadenas que contienen caracteres acentuados o diéresis (à o ä) devolverá ** falso ** si una de las cadenas usaría la descomposición canónica. La ortografía puede ser la misma, no importa. Incluso los resultados peores le darán equalalsIgnoreCase(): las variantes de casos como sharp s o sigma final no serán reconocidos. Eso es solo porque estos métodos usan una comparación binaria que no es adecuada para cadenas internacionales. –
la palabra clave es descomposición canónica. Esta es una característica de lenguaje (natural) y no tiene nada que ver con la represantación de cadenas, de hecho, en la mayoría de los casos, desea que se trate de manera diferente como una cadena. Estoy de acuerdo contigo en equalsIgnoreCase en que uno es malo porque borra la línea entre una Cadena que es solo un contenedor de Caracteres y Palabras en un Idioma/Configuración regional. – Stefan