Ordenar Merge Sort Java
Ordenar Merge Sort Java
Introduccin.
Debido a que en los ltimos tiempos esta parece ser una de las preguntas ms frecuentes que aparecen, me he decidio a escribir este pequeo ejemplo sobre como ordenar elementos. Este ejemplo no trata de ser una gua de buena programacin, si no que trata simplemente de ensear la manera de ordenar fcilmente colecciones de elementos. Como toda persona que trabaja con Java debera saber, el API de Java es muy rico, y contiene ya mucho del cdigo genrico que nuestra aplicacin pueda necesitar. Solo hay que saber buscarlo. Este es el caso de la ordenacin de elementos, que viene ya implementada, con un algoritmo de los ms eficientes, el mergesort. Adems, date cuenta de que, como dice el ttulo, este artculo trata el ordenamiento de objetos, no elementos primitivos.
Method Summary
int compareTo(Object o)
Compares this object with the specified object for order. El entero que devuelve este mtodo ser el equivalente a objeto1 - objeto2, es decir:
objecto1.comparteTo(objeto2); negativo si objeto1 < objeto2 cero si objeto1 = objeto2 positivo si objeto1 > objeto2
Lo que decida si un objeto es mayor o menor que otro es lo que tenemos que hacer nosotros. Por supuesto gran parte de las clases bsicas del API de Java, como String, Integer, File, Date y dems, ya la implementan, con el orden esperado (alfabtico, ordinal, cronolgico, etc), as que solo tendremos que preocuparnos de este interface con nuestras clases propias ms complejas, como por ejemplo, Usuario:
class Usuario{ private String nombre; private int edad; Usuario(String nombre, int edad) { 1
http://www.javahispano.com
this.nombre = nombre; this.edad = edad; } public String getNombre() { return nombre; } public int getEdad() { return edad; } public String toString() { return nombre + " (" + edad + ")"; } }
Nosotros tendremos que decidir que hace que un Usuario vaya antes que otro, pongamos por ejemplo el orden alfabtico.
class Usuario1 implements Comparable { private String nombre; private int edad; Usuario1(String nombre, int edad) { this.nombre = nombre; this.edad = edad; } public String getNombre() { return nombre; } public int getEdad() { return edad; } public String toString() { return nombre + " (" + edad + ")"; } public int compareTo(Object o) { Usuario1 otroUsuario = (Usuario1) o; //podemos hacer esto porque String implementa Comparable return nombre.compareTo(otroUsuario.getNombre()); } }
Esta clase contiene muchos mtodos, para hallar el elemento ms pequeo o el ms grande de una coleccin, para barajearlos (cambiar su orden de forma aleatoria), para ponerlos en orden inverso al actual, etc. Solo teneis que consultar el API. Por supuesto esta clase tiene un mtodo para ordenar colecciones de elementos, y es eso lo que nos ocupa ahora.
Method Summary
static sort(List list) void Sorts the specified list into ascending order, according to the natural
ordering
of its elements. Como veis este mtodo puede ordenar cualquier colecion que implemente el interface java.util.List, y ese orden natural se refiere al orden que indican el mtodo comparteTo que hemos visto antes. Un ejemplo para ordenar distintos java.lang.String sera de la siguietne forma:
ArrayList lista = new ArrayList(); lista.add("uno"); lista.add("dos"); lista.add("tres"); lista.add("cuatro"); printList(lista); System.out.println("\n Ahora ordenados..."); Collections.sort(lista); //metodo que imprime la lista printList(lista);
Method Summary
static sort(List list, Comparator c) void Sorts the specified list according to the order induced by the specified
http://www.javahispano.com
comparator. As que nos pica la curiosidad y vamos a ver que es eso de java.util.Comparator, y descubrimos que es otro interface que se usa para comparar objetos, y que tiene los siguientes mtodos:
Method Summary
int compare(Object o1, Object o2)
Indicates whether some other object is "equal to" this Comparator. El mtodo equals(Object obj) no nos interesa, es el que como en la clase java.lang.Object determina si dos objetos son el mismo o no, el que nos interesa es el otro, compare(Object o1, Object o1). El funcionamiento es el mismo que el visto anteriormente en el interface comparable, solo que en esta ocasin se pasan los dos objetos a comparar como argumentos. El resultado ser:
negativo si o1 < o2 cero si o1 = o2 positivo si o1 > o2
o al menos eso es lo que se espera, porque nosotros podemos decidir. El mtodo sort de la clase java.util.Collections ordenadr en funcin de este resultado, pero somos nosotros quin decide ese orden. Podramos hacer que nuestras clases implementasen java.util.Comparator, pero entonces no habramos avanzado mucho desde el ejemplo anterior, es decir, estaramos limitados a un orden, por lo que lo normal ser escribir distintas clases que implementen este interface para despus usar la que necesitemos en cada momento. Para ordenar nuestra clase Usuario escribiremos dos clases, una para ordenarlos por nombre, y otra por edad.
import java.util.Comparator; class NombreComparator implements Comparator { public int compare(Object o1, Object o2) { Usuario u1 = (Usuario) o1; Usuario u2 = (Usuario) o2; return u1.getNombre().compareTo(u2.getNombre()); } public boolean equals(Object o) { return this == o; } } import java.util.Comparator; class EdadComparator implements Comparator { public int compare(Object o1, Object o2) {
Usuario u1 = (Usuario) o1; Usuario u2 = (Usuario) o2; return u1.getEdad() - u2.getEdad(); } public boolean equals(Object o) { return this == o; } }
No va a tratar bien los acentos ni letras como la Va a ordenar mal los nmeros Ej : 1,10,110,2,3,4,45,5,.... Las maysculas tienen cdigo ASCII menor, por lo que saldrn antes que todas las entradas con minsuculas, etc..
Por lo tanto si lo que quieres hacer es ordenar Strings yo te sugerira algo como esto :
Collator esCollator = Collator.getInstance(new Locale("es", "ES", "EURO")); // EURO es para estar al dia Arrays.sort(myArray,esCollator);
http://www.javahispano.com
Nota : Collator implementa la interfaz Comparator Ventaja frente a currarte tu propio compareTo() para ordenar Strings ? Si en vez de coger el Locale Espaol coges el de la mquina tu programa ordenar bien en cualquier lenguaje.
Alberto Molpeceres es ahora mismo desarrollador de aplicaciones en mbito cliente/servidor para la empresa T-Systems - debis Systemhaus en Munich (Alemania). Cuando no est trabajando o "metiendo caa" al resto de los integrantes de javaHispano intenta pasear con su novia, buscar la desaparecida lgica del idioma alemn o intenta olvidar la pesadilla que es buscar piso en Munich. Para cualquier duda o tirn de orejas, e-mail a: [email protected]