Ordenar Listas en Java

Bien, ordenar una lista en Java, es algo muy sencillo, lo único que tenemos que hacer es llamar al método Sort, de la clase Collections, mandarle cómo parámetro la Lista que queremos ordenar y este los ordenara dado el orden natural del objeto (interfaz Comparable) , y si no queremos eso, pues podemos crear un Comparator. Sin embargo, imaginemos que tenemos aproximadamente unos 20 Objetos diferentes, que son JavaBeans, y que requerimos ordenarlos muchas veces por diferentes propiedades que tengan como por ejemplo Nombre, Apellido Paterno, Apellido Materno o Dirección. Tendríamos que estar creando Comparators para cada una de las propiedades que tenga el JavaBean y de está forma luego ya poder ordenarlos. Tendríamos al menos más de 20 Comparators diferentes que implementan casi la misma lógica, comparar un bean por alguna de sus propiedades, complicado no?. Bueno una solución para esto es el API de Reflection de Java





Bueno para inciar es necesario crear la firma de nuestro método, el cual podemos introducir en una clase Util que tenga métodos que usaremos durante nuestra aplicación, entonces la firma de nuesto método queda así:


import java.util.List;


public class Util {

public static void ordena(List lista, String propiedad) {

}

}

Lo único que hara el método sera recibir una lista, la cual ordenaremos, y la propiedad por la cual queremos ordenarla. Es decir vamos a ordenar una lista de Personas por Edad, entonces lo único que tendríamos que hacer es llamar a nuestro metodo ordena(lista,"nombre"), donde lista, es la Lista de Personas y nombre es una propiedad del JavaBean, es decir tiene métodos de setNombre() y getNombre().



Bien, ahora si pasemos a la parte divertida, para hacer esto, lo único que tenemos que hacer es mandar llamar al metodo Sort de la Clase Collections (la idea original) y crear un Comparator. Sólo que el Comparator, llamara a las propiedades de los objetos en tiempo de ejecución utilizando el API de Reflection de Java. Entonces hasta ahora lo que tenemos es esto:



import java.util.Collections;
import java.util.Comparator;
import java.util.List;


public class Util {

public static void ordena(List lista, String propiedad) {
Collections.sort(lista, new Comparator() {
public int compare(Object arg0, Object arg1) {
return 0;
}
});
}

}






Ahora lo que tenemos que hacer es llamar a los metodos getPropiedad de cada uno de los objetos y compararlos. Esto se logra llamando al método getClass() de la clase Object, luego con esa Clase, llamamaos al método getMethod() y se le manda como pararametro el nombre del método el cual sera getXXXXX donde XXXXX es nuestra propiedad, por ejemplo "nombre" llamara al método getNombre. Y finalmente se invocan esos métodos para obtener las propiedades y luego compararlas. El método invoke() de la clase Method, regresa siempre Object y si el método regresa tipos primitivos regresa su clase encapsuladora (int->Integer etc...).


import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


public class Util {

public static void ordena(List lista, final String propiedad) {
Collections.sort(lista, new Comparator() {

public int compare(Object obj1, Object obj2) {

Class clase = obj1.getClass();
String getter = "get" + Character.toUpperCase(propiedad.charAt(0)) + propiedad.substring(1);
try {
Method getPropiedad = clase.getMethod(getter);

Object propiedad1 = getPropiedad.invoke(obj1);
Object propiedad2 = getPropiedad.invoke(obj2);

//AUN TENEMOS QUE COMPARARLAS

}
catch(Exception e) {
e.printStackTrace();
}





return 0;
}
});
}


}



Por último solo falta comparar las propiedades, para esto utilizaremos el operador instanceof, para saber si la propiedad es comparable utilizando compareTo(), de lo contrario usaremos el metodo equals para comparar los objetos y si no son iguales regresaremos 1 (Que en realidad esto no es de mucha utilidad de cualquier forma jaja, pero es lo único que se puede hacer). Además al parámetro de la propiedad, tenemos que agregar la opcion final, porque será usado dentro de la clase Comparator que estamos definiendo internamente.



import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;



public class Util {

public static void ordena(List lista, final String propiedad) {
Collections.sort(lista, new Comparator() {

public int compare(Object obj1, Object obj2) {

Class clase = obj1.getClass();
String getter = "get" + Character.toUpperCase(propiedad.charAt(0)) + propiedad.substring(1);
try {
Method getPropiedad = clase.getMethod(getter);

Object propiedad1 = getPropiedad.invoke(obj1);
Object propiedad2 = getPropiedad.invoke(obj2);

if(propiedad1 instanceof Comparable && propiedad2 instanceof Comparable) {
Comparable prop1 = (Comparable)propiedad1;
Comparable prop2 = (Comparable)propiedad2;
return prop1.compareTo(prop2);
}//CASO DE QUE NO SEA COMPARABLE
else {
if(propiedad1.equals(propiedad2))
return 0;
else
return 1;

}

}
catch(Exception e) {
e.printStackTrace();
}
return 0;
}
});
}


}



Bien de esta forma tenemos terminado nuestro método, ahora solo falta probarlo, y para esto crearemos un Main, con una Lista de Objetos de Clase Persona, que son un JavaBean y la Ordenaremos. Además al método agregamos una anotación para que elimine las Warnings y el compilador no este dando lata jaja. Por último nuestra clase luce así:


import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;



public class Util {

@SuppressWarnings("unchecked")
public static void ordena(List lista, final String propiedad) {
Collections.sort(lista, new Comparator() {

public int compare(Object obj1, Object obj2) {

Class clase = obj1.getClass();
String getter = "get" + Character.toUpperCase(propiedad.charAt(0)) + propiedad.substring(1);
try {
Method getPropiedad = clase.getMethod(getter);

Object propiedad1 = getPropiedad.invoke(obj1);
Object propiedad2 = getPropiedad.invoke(obj2);

if(propiedad1 instanceof Comparable && propiedad2 instanceof Comparable) {
Comparable prop1 = (Comparable)propiedad1;
Comparable prop2 = (Comparable)propiedad2;
return prop1.compareTo(prop2);
}//CASO DE QUE NO SEA COMPARABLE
else {
if(propiedad1.equals(propiedad2))
return 0;
else
return 1;

}

}
catch(Exception e) {
e.printStackTrace();
}
return 0;
}
});
}

public static void main(String[] args) {
List<Persona> personas = new ArrayList<Persona>();


personas.add(new Persona("Gustavo",25));
personas.add(new Persona("Pedro",32));
personas.add(new Persona("Pablo",15));
personas.add(new Persona("Juan",10));
personas.add(new Persona("Ramiro",50));
personas.add(new Persona("Daniel",81));
personas.add(new Persona("Hector",23));

System.out.print("Lista sin ordenar:");
System.out.println(personas);
System.out.println();


//LLAMAMOS A ORDENA POR NOMBRE
ordena(personas,"nombre");
System.out.print("Ordenadas por Nombre:");
System.out.println(personas);
System.out.println();

//LLAMAMOS A ORDENA POR EDAD
ordena(personas,"edad");
System.out.print("Ordenadas por Edad:");
System.out.println(personas);
System.out.println();

}


}

class Persona {

String nombre;
int edad;



public Persona(String nombre, int edad) {
super();
this.nombre = nombre;
this.edad = edad;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public int getEdad() {
return edad;
}
public void setEdad(int edad) {
this.edad = edad;
}

//SOLO PARA QUE SEA MAS FACIL VER LOS DATOS
public String toString() {
return nombre + " " + edad;
}

}





Aún habría algunas cosas que agregar a nuestro método, cómo manejo correcto de excepciones, ponerlo en una clase más adecuada etc... Pero en Escencia ya está terminado y lo podremos usar y reusar en muchos de nuestros proyectos!



Espero te haya servido
Saludos


Apagar la computadora automáticamente (XP)

A veces nosotros necesitamos dejar la computadora prendida bajando algo o realizando alguna tarea, si nos tuvieramos que ir, nos gustaría poder apagarla automáticamente. Para realizar esto haremos uso de un commando que nos proporciona el sistema operativo.

Para usarlo tenemos que entrar a INICIO -> Ejecutar...

shutdown -s -f - t [tiempoEnSegundos]

Con este comando le decimos que apague la computadora y que si alguna aplicación no responde la finalice, además de asignar el tiempo en que queremos que se apague.

PHP: Un lenguaje Sencillo

En los últimos años, PHP se ha convertido en un lenguaje para programación web muy utilizado, existen muchas aplicaciones desarrolladas utilizándolo y muy grandes (como Facebook). Además, hoy en día es posible programar aplicaciones de escitorio utilizando PHP (sí, ya es posible) utilizando las librerías GTK para la interfaz gráfica. También existe un gran soporte en Internet, hay demasiados foros que contienen información del mismo, una gran cantidad de librerías con funciones ya hechas e incluso paquetes totalmente gratis, gestores de Contenido, Foros, Carritos de Compras, Galerías de Imágenes, Lectores de RSS, entre muchas otras. Cuenta con soporte multiplataforma, las funciones son llamadas nativas (no está implementado sobre ninguna máquina virtual como Java) y cuenta con gran conectividad con MySQL.

Sin embargo hablando como programador, más que como un usuario "que descarga paquetes", creo que PHP es HORRENDO, tiene como origen un modelo de programación en web antiguo, el soporte que tiene para la programación orientada a objetos es nefasto (incluso en PHP5 que dicen que SUPUESTAMENTE mejoró mucho), su naturaleza fomenta en la mayoría de programadores mezclar completamente el código de la lógica del negocio con la vista. El poder utilizar variables donde sea, hace que sea más difícil la corrección de bugs, ya que puede llegar a confundir las variables $id_usuario con $id_usario y tener errores de ejecución, y debido a que PHP "lo permite" es muy dificil de corregir.


PHP no se utiliza para la creación de aplicación empresariales, a veces resulta muy complicado implementar patrones de diseño ya que no tiene gran soporte de la programación orientada a objetos, no es Como Java, que es 100% Orientado a Objetos en el que incluso las funciones nativas o librerías que vienen incluidas en el JRE residen siempre en un objeto. Las empresas de desarrollo, nunca eligen a PHP para un proyecto grande, ya que su arquitectura no lo permite.

Otro problema, el principal y más grande que yo veo en PHP, es que muchos de los programadores que aprenden está tecnología, lo hacen porque necesitan hacer una página web que sea interactiva y que permita el registro de usuarios, no estudian Programación Orientada a Objetos, ni siquiera se preocupan de Patrón Modelo Vista Controlador, hacen un revoltijo en las páginas de código HTML, CSS, Javascript y PHP (Ya que así es como se vende PHP, "APRENDA PHP, Sólo con saber un poco de HTML y CSS). A diferencia de aquellos que aprenden a programar en Java o .NET (no todos) adquieren mejores prácticas de Programación, tienen una mejor idea de cómo hacer un Modelado de un Sistema (aclaro, no todos jeje) y son más disciplinados para programar (REPITO: NO TODOS JAJA).

Se habla mucho acerca de Java VS PHP o .NET VS PHP, sin embargo creo que ni siquiera hay puntos de comparación, .NET y Java, son tecnologías en las que se pueden realizar un sin fin de cosas, aplicaciones web, aplicaciones Standalone, Celulares, Servicios Web, RMI, RPC, DAEMONS, Interpretes, Compiladores. Tienen gran Soporte de Transacciones, y no creo que haya un Framework para aplicaciones web tan completo y tan robusto como Spring. PHP es un lenguaje que sirve para aplicaciones sencillas, carritos de compras y foros, pero no creo que al menos en el corto plazo se pueda comparar con un lenguaje y una Suite tan completa y poderosa como Java. Claro la curva de aprendizaje de Java, es mucho más grande que la de PHP, pero los beneficios que trae también son así, además aprender a programar en un lenguaje de programación como Java hace que los programadores comprendan en funcionamiento de un simple programa y así que puedan ir aprendiendo hasta llegar a comprender un Sistema Distribuido, que utiliza Web Services y bases de datos distribuidas que soporta transacciones, a diferencia de muchos que aprenden PHP, que a veces ni siquiera llegan a comprender el esquema Cliente-Servidor.