Las aplicaciones que buscan u ordenan texto realizan frecuentes comparaciones. Por ejemplo, un navegador necesita comparar la igualdad de dos cadenas cuando los usuarios finales buscan alg�n texto. Un escritor de informes realiza comparaciones de cadenas cuando ordena un lista de cadenas en orden alfab�tico.
Si la audiencia de nuestra aplicaci�n est� limitada a personas de habla inglesa, probablemente podamos hacer las comparaciones con el m�todo String.compareTo. Este m�todo realiza una comparaci�n binaria de caracteres Unicode dentro de las cadenas. Para muchos idiomas, esta comparaci�n binaria no es suficiente para ordenar cadenas, porque los valores Unicode no corresponden con el orden relativo de los caracteres.
Afortunadamente, la clase Collator permite realizar comparaciones de cadenas en diferentes idiomas. En esta lecci�n, veremos c�mo utilizar la clase Collator para buscar y ordenar texto.
�Realizar Comparaciones Independientes de la Localidad
Las reglas de comparaci�n definen la secuencia de ordenaci�n de los strings. Estas reglas pueden variar con la Localidad, porque los distintos idiomas naturales ordenan sus palabras de forma diferente. Utilizando las reglas predefinidas de la clase Collator, podemos ordenar cadenas de una forma independiente de la Localidad.
Se utiliza la clase Collator para realizar comparaciones independientes de la Localidad. Esta clase es sensible a la Localidad. Para ver las localidades soportadas por la clase Collator, se llama al m�todo getAvailableLocales.
Locale[] locales = Collator.getAvailableLocales();
Para ejemplarizar la clase Collator, se llama al m�todo getInstance y se especifica una Localidad.
Collator myCollator = Collator.getInstance(new Locale("en", "US"));
El m�todo getInstance realmente devuelve un RuleBasedCollator, que es una subclase concreta de Collator. El objeto RuleBasedCollator contiene un conjunto de reglas que determinan el orden de ordenaci�n de las cadenas para una localidad especificada. Estas reglas est�n predefinidas para cada localidad. Como estas reglas est�n encapsuladas dentro de RuleBasedCollator, los programas no necesitar�n rutinas especiales para tratar con las reglas de comparaci�n para varios idiomas.
Se llama al m�todo Collator.compare para realizar comparaciones de cadenas independientes de la Localidad. Este m�todo devuelve un entero menor que, igual que o mayor que cero cuando la cadena del primer argumento sea menor que, igual que o mayor que la cadena del segundo argumento.
System.out.println(myCollator.compare("abc", "def")); System.out.println(myCollator.compare("rtf", "rtf")); System.out.println(myCollator.compare("xyz", "abc"));
Aqui puedes ver la salida del programa anterior.
-1 0 1
Utilizaremos el m�todo compare para realizar operaciones de ordenaci�n. El programa de ejemplo, llamado CollatorDemo.java utiliza el m�todo compare para ordenar un array de palabras Inglesas y Francesas. En este programa, veremos lo que sucede cuando se ordena un array con dos objetos Collator diferentes.
Collator fr_FRCollator = Collator.getInstance(new Locale("fr","FR")); Collator en_USCollator = Collator.getInstance(new Locale("en","US"));
Nuestro m�todo para ordenar, llamado sortStrings, puede ser utilizado con cualquier Collator. Observa que el m�todo sortStrings llama al m�todo compare.
public static void sortStrings(Collator collator, String[] words) { String tmp; for (int i = 0; i < words.length; i++) { for (int j = i + 1; j < words.length; j++) { // Compare elements of the array two at a time. if (collator.compare(words[i], words[j] ) > 0 ) { // Swap words[i] and words[j] tmp = words[i]; words[i] = words[j]; words[j] = tmp; } } } }
El Collator Ingl�s ordena las palabras de esta forma.
peach p�che p�ch� sin
De acuerdo a las reglas de comparaci�n del idioma Franc�s, la lista anterior ser�a err�nea. En Franc�s, "p�che" deber�a seguir a "p�ch�" en una lista ordenada. Nuestro Collator Franc�s ordena del array de forma correcta.
peach p�ch� p�che sin
�Personalizar la Reglas de Comparaci�n
En algunos casos, las reglas predefinidas de comparaci�n proporcionadas por la clase Collator podr�an no ser suficiente. Por ejemplo, podr�amos querer ordenar strings en un idioma cuya localidad no estuviera soportada por Collator. En esta situaci�n, podemos definir nuestras propias reglas de comparaci�n, y asignarlas a un objeto RuleBasedCollator.
En la secci�n anterior, explicamos como realizar comparaciones de cadenas utilizando diferentes reglas para cada localidad. Estas reglas de comparaci�n determinan el orden de ordenaci�n de las cadenas. Si las reglas predefinidas no son suficientes, podemos dise�ar nuestras propias reglas y asignarlas a un objeto RuleBasedCollator.
Las reglas de comparaci�n personalizadas est�n contenidas en un objeto String que se pasa al constructor de RuleBasedCollator. Aqu� tenemos un ejemplo.
String simpleRule = "< a < b < c < d"; RuleBasedCollator simpleCollator = new RuleBasedCollator(simpleRule);
Para el objeto simpleCollator del ejemplo anterior, "a" es menor que "b," que es menor que "c," y as� sucesivamente. El m�todo simpleCollator.compare se referir� a estas reglas cuando compare cadenas. La s�ntaxis completa utilizada para construir una regla de comparaci�n es m�s flexible y completa que ese sencillo ejemplo. Para una completa descripci�n de la s�ntaxis, puedes ver a la documentaci�n del API para la clase RuleBasedCollator.
En el siguiente ejemplo ordenamos una lista de palabras espa�olas con dos objetos Collators. El c�digo completo de este ejemplo est� en el fichero llamado RulesDemo.java.
Empezamos definiendo nuestras propias reglas de ordenaci�n para Ingl�s y Espa�ol. Hemos decidido ordenar las palabras en Espa�ol de la forma tradicional. Cuando se ordena de esta forma, las letras "ch," y "ll," y sus may�sculas equivalentes. tienen su propia posici�n en el orden de ordenaci�n. Estas parejas de caracteres se comparan como si fueran un s�lo caracter. Por ejemplo, "ch" ordena com una s�la letra despu�s de "cz". Observa las diferencias para los dos Collators.
String englishRules = ("< a,A < b,B < c,C < d,D < e,E < f,F " + "< g,G < h,H < i,I < j,J < k,K < l,L " + "< m,M < n,N < o,O < p,P < q,Q < r,R " + "< s,S < t,T < u,U < v,V < w,W < x,X " + "< y,Y < z,Z"); String smallnTilde = new String("\u00F1"); String capitalNTilde = new String("\u00D1"); String traditionalSpanishRules = ("< a,A < b,B < c,C " + "< ch, cH, Ch, CH " + "< d,D < e,E < f,F " + "< g,G < h,H < i,I < j,J < k,K < l,L " + "< ll, lL, Ll, LL " + "< m,M < n,N " + "< " + smallnTilde + "," + capitalNTilde + " " + "< o,O < p,P < q,Q < r,R " + "< s,S < t,T < u,U < v,V < w,W < x,X " + "< y,Y < z,Z");
En las siguientes l�neas de c�digo, creamos los Collators y llamamos a nuestra rutina de ordenaci�n.
try { RuleBasedCollator enCollator = new RuleBasedCollator(englishRules); RuleBasedCollator spCollator = new RuleBasedCollator(traditionalSpanishRules); sortStrings(enCollator, words); printStrings(words); System.out.println(); sortStrings(spCollator, words); printStrings(words); } catch (ParseException pe) { System.out.println("Parse exception for rules"); }
La rutina de ordenaci�n, llamada sortStrings, es gen�rica. Ordena cualquier array de palabras de acuerdo a las reglas de cualquier objeto Collator.
public static void sortStrings(Collator collator, String[] words) { String tmp; for (int i = 0; i < words.length; i++) { for (int j = i + 1; j < words.length; j++) { // Compare elements of the words array if( collator.compare(words[i], words[j] ) > 0 ) { // Swap words[i] and words[j] tmp = words[i]; words[i] = words[j]; words[j] = tmp; } } } }
Cuando ordenamos con las reglas de ordenaci�n Inglesas el array aparecer� de esta forma.
chalina curioso llama luz
Compara la lista anterior con la siguiente, que est� ordenada de acuerdo a las reglas de ordenaci�n del Espa�ol tradicional.
curioso chalina luz llama
�Aumentar el Rendimiento de la Comparaci�n
Con la clase CollationKey, podremos incrementar la eficiencia de la comparaci�n de cadenas. Esta clase convierte objetos String a claves cortas que siguen las reglas de un objeto Collator dado.
La ordenaci�n de largas listas de palabras consume mucho tiempo. Si el algoritmo de ordenaci�n compara cadenas repetidamente podemos acelerar el proceso utilizando la clase CollationKey.
Un objeto CollationKey representa una clave de ordenaci�n para un String y un Collator dados. Comparar dos objetos CollationKey envuelve una amplica comparaci�n de claves cortas que es m�s r�pido que comparar objetos String con el m�todo Collator.compare. Sin embargo, generar objetos CollationKey tambi�n necesita tiempo. Por lo tanto, si un String s�lo va a ser comparado una vez, Collator.compare ofrece mejor rendimiento.
En el siguiente ejemplo, utilizamos un objeto CollationKey para ordenar un array de palabras. El c�digo completo de este ejemplo est� en el fichero llamado KeysDemo.java.
Creamos un array de objetos CollationKey en el m�todo main. Para crear un CollationKey, se llama al m�todo getCollationKey sobre un objeto Collator. No se pueden comparar dos objetos CollationKey que no sean originales del mismo objeto Collator. Aqui podemos ver el m�todo main.
static public void main(String[] args) { Collator enUSCollator = Collator.getInstance(new Locale("en","US")); String [] words = { "peach", "apricot", "grape", "lemon" }; CollationKey[] keys = new CollationKey[words.length]; for (int k = 0; k < keys.length; k ++) { keys[k] = enUSCollator.getCollationKey(words[k]); } sortArray(keys); printArray(keys); }
El m�todo sortArray llama al m�todo CollationKey.compareTo. Este m�todo devuelve un entero menor que, igual que, o mayor que cero si el objeto keys[i] es menor que, igual que o mayor que el objeto keys[j]. Observa que hemos comparado los objetos CollationKey, no los objetos String del array original de palabras. Aqu� puedes ver el c�digo del m�todo sortArray.
public static void sortArray(CollationKey[] keys) { CollationKey tmp; for (int i = 0; i < keys.length; i++) { for (int j = i + 1; j < keys.length; j++) { // Compare the keys if( keys[i].compareTo( keys[j] ) > 0 ) { // Swap keys[i] and keys[j] tmp = keys[i]; keys[i] = keys[j]; keys[j] = tmp; } } } }
Hemos ordenado un array de objetosCollationKey, pero nuestro objetivo original era ordenar un array de objetos String. Para recuperar el String que representa a cada objeto CollationKey, llamamos al m�todo getSourceString en el m�todo displayWords.
static void displayWords(CollationKey[] keys) { for (int i = 0; i < keys.length; i++) { System.out.println(keys[i].getSourceString() + " "); } }
El m�todo displayWords imprime las siguientes l�neas.
apricot grape lemon peach