## Personalizar las Reglas de Comparación

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

Ozito