Duda de ordenamiento de una lista

Hola buen día alguno de ustedes podría explicarme por favor en que se basa java para ordenar una lista de string, tengo el siguiente ejemplo:

import java.util.*;
public class ASort{
    public static void main(String[] args) {
        ArrayList<String> strings = new ArrayList<String>();
        strings.add("aBaB");
        strings.add("BaB");
        strings.add("aBa");
        strings.add("BBaa");
        Collections.sort(strings);
        for (String s : strings) { System.out.print(s + " "); }
    }
}

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Para ordenar strings lo hace

Para ordenar strings lo hace alfabeitcamente, las mayúsculas van primero y las minúsculas después.

Es por eso que "BBaa" aparece antes que "aBa"

Imagen de benek

Interfaz Comparable.

Hablando internamente, Collections.sort() se basa en la implementación que se haya hecho de la interfaz Comparable en el objeto. Cuando necesitamos que los objetos de una clase puedan ser ordenados hacemos que éstos implementen Comparable y definimos el método compareTo(), en el cuál viene la regla para determinar cuándo un objeto es mayor, igual o menor que otro.

Para la clase String y demás wrappers, el comportamiento ya viene implementado para que se ordene de acuerdo al orden natural del valor que permite cada tipo de dato, por ejemplo String ordena alfabéticamente, Integer ordena numéricamente, etc... Puedes corroborar esto viendo la implementación de compareTo() de la clase Java (del proyecto Harmony, pe: http://www.docjar.com/html/api/java/lang/String.java.html

Pero para las clases normales que creamos, este comportamiento no está definido por supuesto. Suponiendo que tenemos una clase DVD.java, nosotros debemos definir en base a qué regla se hará dicha comparación, implementando Comparable y sobreescribiendo compareTo(), más o menos así:

import java.lang.Comparable;

public class DVD implements Comparable<DVD>{
       
        String titulo;
        String genero;
        String protagonista;
       
        public DVD(String titulo, String genero, String protagonista){
                this.titulo = titulo;
                this.genero = genero;
                this.protagonista = protagonista;
        }
       
        @Override
        public int compareTo(DVD dvd){
                return titulo.compareTo(dvd.getTitulo());
        }
       
        //Getters & Setters

}

En este caso, estoy definiendo que el ordenamiento se haga en base al título de cada objeto DVD, compareTo() devuelve un entero para indicar si el objeto a comparar es mayor cuando el entero es positivo, menor cuando el entero es negativo o igual si el entero es 0. Así es como Collections.sort() va ordenando una lista de DVD's.

Imagen de benek

Comparator.

También existe otra interfaz, Comparator, para el mismo propósito.

La diferencia es que Comparable se implementa en la clase de los objetos que serán comparados, mientras Comparator se implementa en clases que servirán como ordenamientos mismos. Por eso con Comparable solamente podemos definir un ordenamiento, mientras que podemos crear los ordenamientos que necesitemos con Comparator. En resumen, Comparable puede definir el ordenamiento por default (uno solo), y Comparator ordenamientos adicionales.

Suponiendo que el mismo DVD queremos que se ordene por Género y por Protagonista, haremos entonces dos clases para ordenamiento:

import java.util.Comparator;

public class OrdenamientoPorGenero implements Comparator<DVD>{
        @Override
        public int compare(DVD uno, DVD dos){
                return uno.getGenero().compareTo(dos.getGenero());
        }
}

import java.util.Comparator;

public class OrdenamientoPorProtagonista implements Comparator<DVD>{
        @Override
        public int compare(DVD uno, DVD dos){
                return uno.getProtagonista().compareTo(dos.getProtagonista());
        }
}

En este caso, no hay que modificar nada en la clase DVD, simplemente al utilizar Collections.sort() le indicamos el parámetro de qué ordenamiento utilizar.

                OrdenamientoPorGenero porGenero = new OrdenamientoPorGenero();
                System.out.println("Ordenamiento por género:");
                Collections.sort(dvds, porGenero);
                for (DVD dvd : dvds){
                        System.out.println(dvd);
                }

                OrdenamientoPorProtagonista porProtagonista = new OrdenamientoPorProtagonista();
                System.out.println("Ordenamiento por protagonista:");
                Collections.sort(dvds, porProtagonista);
                for (DVD dvd : dvds){
                        System.out.println(dvd);
                }              

Saludos.

El comparator para hacer comparaciones customizadas

Por ejemplo si se necesitara en orden inverso sería:

Collections.sort( strings, new Comparator<String>() {
    public int compare( String a, Sring b ) {
        return b.compareTo( a );// primero el b y luego el a
     }
});

O para ordenarlos por longitud

Collections.sort( strings, new Comparator<String>() {
    public int compare( String a, Sring b ) {
        return a.lenght() - b.lenght();
     }
});