Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Más Reflexión

Reflection es un API de Java que es muy útil y que es utilizada por muchos frameworks de Java, como Spring, Struts o Trapestry, ya que permite acceder a métodos, atributos y ver el comportamiento de una clase durante la ejecución del programa.

Reflection puede servir para crear entornos de desarrollo visuales, herramientas que sirvan para realizar pruebas a algún componente, herramientas de depuramiento (aka debugging) o algún marco de trabajo que cree instancias e inyecte propiedades de objetos a partir de un archivo de configuración

Así que está vez muestro una clase que realizó un compañero de trabajo ya hace algunos años y que permite crear instancias y/o acceder a las propiedades (a tráves de los métodos accesores) de manera reflexiva. Esta es una herramienta muy útil ya que permite obtener propiedades de objetos de manera que podemos usarla para ordenar beans de manera mas general sin tener que definir un comparator para cada bean dependiendo de la propiedad que se desee comparar, convertir una lista de un beans en un mapa o crear listas de con alguna de las propiedades del bean.


/*
* GenericBean.java
*
* Created on 22 de junio de 2006, 09:32 PM
*

*/

/**
*
* @author JM
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class GenericBean {
private Object o;
private Class beanClass;

/** Creates a new instance of GenericBean */
public GenericBean(String className) {
try {
beanClass = Class.forName(className);
Constructor c = beanClass.getConstructor();
o = c.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}

public GenericBean(Object instance) {
o = instance;
beanClass = o.getClass();
}

public Object get(String property) {
Object ret = null;
property = property.substring(0, 1).toUpperCase()
+ property.substring(1);
try {
String methodName = "get" + property;
Method method = beanClass.getMethod(methodName);
ret = method.invoke(o);
}
catch(Exception e) {
try {
String methodName = "is" + property;
Method method = beanClass.getMethod(methodName);
ret = method.invoke(o);
}
catch(Exception ex) {
e.printStackTrace();
}
}

return ret;
}

public void set(String property, Object value) {
property = property.substring(0, 1).toUpperCase()
+ property.substring(1);
try {
Method method = beanClass.getMethod("set" + property, value
.getClass());
method.invoke(o, value);
} catch (Exception e) {
e.printStackTrace();
}
}

public Object getObject() {
return o;
}

public Class getObjectClass() {
return o.getClass();
}
}

Mañana escribiré como poder usar esta clase, porque la verdad ahorita ya es un poco noche jeje y ya me estoy quedando dormido. Sólo como recordatorio adicional, es importante recordad que utilizar Reflection genera bajas en el performance la máquina virtual ya que muchas veces no es posible utilizar los optimizadores con los que cuenta la JVM, como pueden ser en multiples llamadas a métodos, recursiones de cola etc...

Saludos
Gus

Anotaciones en Java

Nivel: Intermedio

Las anotaciones en Java, son marcas que se hacen a una parte del programa, que no tienen un efecto directo sobre el mismo pero que son reflexivas en la ejecución, es decir, pueden ser utilizadas por algún contenedor al momento de la ejecución del programa.


Las anotaciones son un tipo especial de modificador y puede ser usando junto a otros modificadores, tales como public, static, private etc... Digamos que las anotaciones son una forma de implementar una interfaz, sin que la clase lo haga directamente. Por ejemplo, creas un clase Perro, y entonces la anotas para decir que es un Animal, de está manera, en la ejecución del programa y utilizando reflexión es posible saber que cualquier objeto de clase Perro es un animal. Es decir estamos indicando que Perro es un animal y cumple una función similar a una interfaz.


@Animal
public class Perro {
//Algún buen metodo de la clase perro
}




Definir una anotación es algo muy sencillo, se hace de igual forma que una interfaz y se antepone una "@" al inicio de la palabra interface, y los métodos que contenga serán los elementos de la anotación, y sólo pueden regresar tipos primitivos, String y Enums.





public @interface Animal {
boolean vertebrado();
}


Con la anotación presentada anteriormente, podremos anotar alguna clase y definir si el Animal que estamos anotando es vertebrado o invertebrado


@Animal( vertebrado = true )
public class Perro {

}



De está forma en la ejecución del Programa podemos saber si que un objeto de clase Perro es un animal, y que tipo de animal es, además podemos especificar que la anotación solo sirve para anotar clases, ya que no podemos tener métodos de tipo animal. Y para hacer esto anotamos nuestra anotación. Entonces nuestra anotación queda así:


package anotaciones;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;



@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Animal {

boolean vertebrado();

}



De esa forma específicamos que la anotación sólo sirve para definir tipos. Ahora cómo usarlo en la ejecución:




package anotaciones;

import java.util.ArrayList;
import java.util.List;

public class Main {

@SuppressWarnings("unchecked")
public static void main(String[] args) {

//Creamos una Lista
List obj = new ArrayList();

//Agregamos 2 Perros
obj.add(new Perro());
obj.add(new Perro());

//Agregamos 1 String
obj.add("Soy un String");

System.out.println("Numero de animales en la lista:" + contarAnimales(obj));
}


public static int contarAnimales(List o ) {
if(o==null)
return 0;
else {
System.out.println("Empezando a contar");
int count = 0;
for (Object object : o) {
//System.out.println(object.getClass().getAnnotation(Animal.class));
if(object.getClass().isAnnotationPresent(Animal.class)) {
count++;
}
}
return count;
}
}

}



Aunque el ejemplo no es de lo más ortodoxo, da una muestra de lo que pueden hacer las anotaciones, y de como que es las utilizan los frameworks como JAXB o Spring 2.5 Anotado, en el cual se puede hacer el Autoalambrado, definir controlador, mapeos de request con anotaciones evitando tener que configurar un dispatcher servlet muy grande.

Saludos

Correr Archivos Jar en Vista

Si algún programa que instalamos como puede ser Winrar u otro compresor de datos se “adueño” de la asociación de los archivos jar podemos regresar esta asociación con la JVM para que al dar doble click en un archivo jar lo abra.

Para poder hacer esto solo es necesario bajar y correr el programa JarFix.

http://www.jonelo.de/java/jarfix/

Oracle compra Sun

El día 20 de Abril Oracle anunció que compraría Sun Microsystems por una suma de $7400 millones de dólares ( $7.4 billion dollars ) y cada acción se compro en 9.54 dólares. Por el momento sólo fue aceptado como un hecho unánime en Sun Microsystems, aunque aún falta que la transacción sea autorizada por el Gobierno.

Más información en:
http://www.bloomberg.com/apps/news?pid=20601087&sid=aVWptwRiZl1w&refer=home

Crear funciones Nativas en Java...DLL

Bueno a veces es necesario crear funciones que sean dependientes del Sistema y que por lo tanto no pueden ser implementadas en Java, para eso existe JNI (Java Native Interface), que sirve para llamar a funciones nativas del Sistema y que pueden estar en un DLL (En Windows). Bien ahora veremos cómo crear una función nativa y que está sea llamada en Java. Lo primero que tenemos que hacer es crear una clase, y que tenga definido un método nativo, a su vez, la clase cargara una librería que se llamara "Project1" (así fue como le puso mi compilador de C jajaja) luego en el main, instanciaremos el objeto y llamaremos a la función:

public class HelloWorld {

public native void sayHello();

static {
System.loadLibrary("Project1");
}

public static void main(String[] args) {
new HelloWorld().sayHello();
}


}

El ejemplo es muy simple, sólo tenemos una clase con un método nativo, un bloque estático que carga una librería de nombre Project1, y un main, el cual crea la instancia y manda a llamar al método.Y ahora solo compilamos la clase:

javac HelloWorld.java

Ahora lo que tenemos que hacer es crear un header de C, que contenga la definición de la función que tenemos que implementar, Java tiene una herramienta para esto y entonces vamos a la línea de comandos de nuevo y tecleamos:

javah HelloWorld

Vamos a la carpeta donde estaba nuestra clase y ahi podemos ver que hay un archivo llamado HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_sayHello
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


Este Header contiene la definición de la función que va a llamar la librería, ahora solo tenemos que crear una implementación que lucirá más o menos cómo esto:


#include
#include "HelloWorld.h"
#include

JNIEXPORT void JNICALL
Java_HelloWorld_sayHello(JNIEnv *env, jobject obj)
{
printf("Hello world Im a C Function\n");
return;
}


Y tenemos que compilar esto en un DLL, que es la parte un poco tediosa aunque si ya has usado alguna vez un compilador de C o C++ no tiene gran problema, puedes usar Borland, Blodshed Dev C++ ó el Visual C++. Yo lo compile con el Blodshed Dev C++ y aquí van las instrucciones:

1.- Una vez que tengas el archivo HelloWorld.h, abre el Bloodshed Dev C++ y crea un nuevo proyecto en la misma carpeta donde está el archivo, el proyecto especifica que sea de tipo DLL. (He aquí porque mi dll se llama Project1 jaja)

2.- Ve a Tools->Compiler Options, cuando abra el cuadro de diálogo, ve a la pestaña de Directories y luego a C++ Includes. (o a C includes dependiendo del tipo de proyecto que hayas creado) Ahi haz clic en el botoncito ese que es como una carpetita, y ve hasta donde este instalado tu Java y agrega la siguientes carpetas $JAVA_HOME\include y $JAVA_HOME\include\win32, donde $JAVA_HOME = Directorio donde está instalado tu Java, en mi caso: C:\Program Files\Java\jdk1.6.0_11, entonces mis rutas quedan así:
C:\Program Files\Java\jdk1.6.0_11\include
C:\Program Files\Java\jdk1.6.0_11\include\win32

3.- En el archivo .cpp que crea automáticamente el IDE copia el Siguiente código:

#include
#include "HelloWorld.h"
#include

JNIEXPORT void JNICALL
Java_HelloWorld_sayHello(JNIEnv *env, jobject obj)
{
printf("Hello world Im a C++\n");
return;
}

Y ve a Execute->Compile, y tu programa debe compilar y generar un archivo de nombre "Project1.dll" (o como le hayas puesto al proyecto.

Luego sólo ve a linea de comandos de nuevo y ejecuta:


java HelloWorld


Y el resultado debe ser:
Hello world Im a C Function

Y así has llamado a una función nativa :D Felicidades!

Espero te haya servido

Saludos!

Classpath en Java

Bueno, cuando estamos empezando a programar en Java, siempre existe la pregunta ¿Qué es el Classpath? Bueno, pues es muy simple, como lo dice su nombre es la ruta de clases que serán usadas para compilar y/o ejecutar un programa. Y su función es poder acceder a clases que están fuera del proyecto, cómo alguna librería externa, existen dos principales formas de configurar un Classpath, la 1era es configurar una variable de entorno del sistema de nombre CLASSPATH, y ahi ir colocando cada una de las carpetas o archivos *.jar que tenemos. La 2da es Compilar escribiendo directamente el Classpath como un parámetro al compilador de está forma:


javac -cp "RUTA" HolaMundo.java


Bueno ahora, para encontrar un uso, imaginemos que tenemos una libería de clases en la carpeta C:/lib, y ahí se encuentra la clase "Libreria"


public class Libreria {


public static void imprimir(String mensaje) {
System.out.println(mensaje);
}

}


Ahora imagina que la quieres usar en otro programa :

public class HolaMundo {

public static void main(String[] args) {

Libreria l = new Libreria();
l.imprimir("Hola Mundo");
}

}


Para poder compilar esto, tenemos que indicarle al compilador el CLASSPATH, que va a usar para compilar la clases y para eso hacemos esto:


javac -cp "C:\lib" HolaMundo.java


Y también para correr el programa se requiere especificar el classpath de la misma manera ya que de lo contrario obtendremos NoClassDefFoundError, porque no va a encontrar todas las clases necesarias. Entonces lo que hacemos es algo muy similar, excepto que está vez tenemos que indicar también la ruta en la que estamos y eso se hace con un "punto":


java -cp "C:\lib;." HolaMundo


Y con eso ya podemos corre nuestra clase.


Saludos!

Compilar todo un paquete java

Cuando compilamos un archivo java tenemos que usar la herramienta "javac"

javac Archivo.java

El problema lo tenemos cuando tenemos los archivos en paquetes y tenemos que compilar estos paquetes. Podriamos compiilar archivo por archivo pero tendriamos problema si estos archivos tienen referencias entre ellos por lo que habría compilar en un orden especifico los archivos. Para solucionar esto nos tenemos que poner en el directorio "root" del proyecto y aplicar la herramienta javac:

javac paquete/subpaquete/*.java

Esto nos compilará todo los archivos en ese paquete sin problemas, sin tener que estar compilando uno por uno.

Singleton: Mejorado

El Singleton, que presenté en mi entrada anterior es la implementación más común de un Singleton, sin embargo aun tiene algunos defectos, entre ellos está es que si esa clase la hacemos serializable, en cada ejecución se crearían diferentes instancias del singleton y tendríamos que crear un método para proteger esto. Y también tenemos el problema de que se puede accesar al constructor privado utilizando el API Reflection. Entonces aquí tenemos una forma más elegante de crear un Singleton:







public enum Singleton {

INSTANCE;

public void doSomething() {

}

}





Y luego cuando lo quisieramos usar, lo único que tendríamos que hacer sería esto:




public class Principal {

public static void main(String[] args) {
Singleton.INSTANCE.doSomething();
}

}




Y con eso tenemos una mejor y más sencilla implementación de un Singleton que nos garantiza que siempre será una única instancia.
SaludoSS!



Referencias:

Blooch, J. Effective Java 2nd Edition

Singleton en Java

Bien, un Singleton en términos muy generales es un objeto del cuál sólo podremos tener una instancia (es decir sólo podemos construir un objeto de esa clase durante la ejecución del programa). Programar un Singleton en Java es muy sencillo, lo único que tenemos que hacer es evitar que otras clases tengan acceso al constructor de mi clase singleton, y ¿cómo se hace eso? Pues sólo tenemos que hacer el constructor Privado, y luego hacemos un método que nos regrese la única Instancia creada.



public class Singleton {


//LA UNICA INSTANCIA QUE SERÁ CREADA
//LA CREAMOS DESDE QUE SE CARGUE LA CLASE
private static Singleton instancia = new Singleton();


//HACEMOS EL CONSTRUCTOR PRIVADO
//PARA QUE SÓLO PUEDA INSTANCIA OBJETOS DESDE LA MISMA CLASE
private Singleton() {
}


//MÉTODO PARA OBTENER LA INSTANCIA
public Singleton getInstance() {
return instancia;
}



}





En este ejemplo la instancia se crea, desde que se crea la clase, pero a veces es mejor crear la instancia hasta que se pide, entonces el código quedaría algo así:


public class Singleton {



//CREAMOS LA REFERENCIA
//AUNQUE AL INICIO APUNTA A NULL
private static Singleton instancia ;


//HACEMOS EL CONSTRUCTOR PRIVADO
//PARA QUE SÓLO PUEDA INSTANCIA OBJETOS DESDE LA MISMA CLASE
private Singleton() {
}


//MÉTODO PARA OBTENER LA INSTANCIA
public Singleton getInstance() {
if(instancia==null) //SI ES NULL
instancia = new Singleton(); //LO INSTANCIAMOS
return instancia;
}



}



Y con esto creamos nuestra clase Singleton, Luego ya le podemos programar métodos adicionales que son los servicios que va a ofrecer.

Saludos

Borrar Archivos con Java

Para poder borrar archivos del disco duro, primero tenemos que realizar una clase File

java.io.File file = java.oi.File("String con la ruta");
file.delete();



Este método nos regresa un boolean si es que lo pudo borrar.

En caso de que necesitemos crear archivos temporales y que se borren cuando terminemos el programa, podemos hacer uso de otro método de la clase file.


java.io.File file = java.oi.File("String con la ruta");
file.deleteOnExit();



Este metodo es void, pues como no es instantaneo no puede garantizar el borrado del archivo. Los archivos se borraran cuando el programa que los llamó se cierre.

Introducción a ANT

Nivel: Intermedio

ANT es una herramienta que se utiliza cuándo se está realizando un proyecto de programación y es necesario estar repitiendo tareas repetitivas cómo la compilación y la construcción. Ant está hecho en Java y es muy similar a Make, pero con las ventajas de ser multiplataforma y de no depender de las instrucciones del sistema operativo, sino que se configura con archivos XML. ANT es un proyecto open-source de la Apache Software Foundation.

Bien para comenzar a usar ANT, lo primero que hay que hacer es descargarlo de la página de apache, pueden escribir en google ANT y será alguno de los primeros resultados, sino aquí está la liga:

http://ant.apache.org/bindownload.cgi

Una vez que hayas descargado ANT, descomprime el arcihvo, ve al directorio /bin y agrega ese directorio al PATH de la Computadora, para que de esta forma, lo puedes llamar fácilmente y no tengas que escribir la ruta completa desde la línea de comandos. Probablemente tengas algunos problemas con el nombre de la carpeta, por los puntos y los guiónes medios, lo que yo hice fue cambiarle el nombre de la carpeta, y así el PATH me quedó asi: C:\ant\bin. También es necesario que tengas Java al menos 1.4. Finalmente para comprobar que lo hiciste bien escribe en una línea de comandos (MS-DOS).ant -version

Y si lo configuraste bien entonces verás información acerca de la versión de Ant que hayas descargado, sino está bien configurado te dirá que ant no es un comando reconocido.

Bien, ahora si vamos a la parte de usar ANT :D. Como ya mencione ANT es una herramienta que sirve para realizar procesos que es necesario repetir muchas veces cuándo estamos desarrollando un proyecto, cómo por ejemplo estar compilando y que tengamos una buena organización de directorios, y queremos separar nuestros archivos fuente de los ya compilados. Y que además se genere automáticamente un jar para correrlo.

Para usar ANT lo único que tenemos que hacer es crear un archivo XML de configuración el cual contendrá las instrucciones de que es lo queremos hacer. En ANT tenemos que configurar un target, que es la opción que va a ejecutar y luego las tareas que queremos que realice cuando seleccionemos ese objetivo. Bien para iniciar, vamos a establecer un nuevo proyecto, crearemos una carpeta que se llamara introduccionant, y ahí meteremos dos archivos:

HolaMundo.java (El Archivo que vamos a compilar y correr con ant)
build.xml (El Archivo de configuración de ANT)

HolaMundo.java
public class HolaMundo {

public static void main(String[] args) {

System.out.println("Hola Mundo");

}

}


build.xml


basedir="."
default="compilar">


debug="true"
deprecation="false"
optimize="false"
failonerror="true">






Primero definimos un proyecto, le damos un nombre, le ponemos el directorio base, en este caso es el mismo y por eso estamos poniendo el "." y el Target que por default va a ejecutar es el de nombre compilar. 

Después de eso tenemos que definir el target, el cuál tiene nombre compilar (es el default) Y en seguida se colocan las tareas que queremos realizar, en este caso solo queremos llamar a javac para que compile los archivos, nuestro directorio destino será el mismo y además colocamos unas opciones adicionales. Además cuando usamos javac, es obligatorio que tengamos definido donde están los archivos fuente por eso definimos también el directorio fuente que en este caso y por simplicidad también es el mismo.

Ahora lo único que tenemos que hacer es ir a una línea de comandos ir al directorio introduccionant y ejecutar el comando:

ant

Una vez esto el resultado dirá que el build se ha hecho satisfactoriamente y para los que han usado NetBeans, verán que la salida de consola es igual a la del IDE, esto es porque NetBeans utiliza Ant para hacer el build de nuestros proyectos. Y si vas al directorio utilizando un Explorador verás que tu archivo .class ya fue creado y puedes escribir en la línea de comandos: 

java HolaMundo

Linea de Comandos con Ant

Bien con eso hemos compilado nuestro primer programa utilizando ant, ahora lo único que tenemos que hacer es agregar más opciones a nuestro archivo build.xml para que podamos realizar más cosas utilizando ANT.

Saludos

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


Copia de Arreglos

Los arreglos son una forma importante de salvar datos. En caso de que tengamos que realizar una copia de arreglos podemos realizarlo de esta manera.

public class Copy(){  
int[] array = new int[55555];
}

public int[] copyArray(){
int[] arrayCopy = new int[array.length];
for( int i = 0; i < array.length; i++ )
arrayCopy[i] = array[i];
return arrayCopy;
}


Para cada posición copiamos el valor de un arreglo al otro, esta es una manera pero existe una mejor y más sencilla. Para eso revisaremos la documentación ( API documentation ); Existe en la clase System un método llamado arraycopy.

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length)

Este método es nativo, por lo que la copia se hará en segmento de memoria haciendola más rápida. Este método nos da la posibilidad de copiar también segmentos del arreglo original.

System.arraycopy(array, 5, array, 0, array.length-5);

Copiando desde la posición 5 del arreglo

Bibliography:

Dactonta, Michael C; Monk, Eric; Keller Paul, Java Pitfalls, Wiley 2000;


Crear un cronómetro

Java es uno de los lenguajes de programación más utilizados o por lo menos de los mas famosos. Una de sus debilidades es la velocidad de ejecución (que ha ido mejorandose) y el consumo de memoria RAM,

Para poder realizar los famosos "benchmarks" lo que podemos medir es el tiempo de ejecución, esto lo podemos realizar a través de una clase que simulará un cronómetro.

public class Stopwatch {
private long startTime = -1;
private long stopTime = -1;
private boolean running = false;

public Stopwatch start(){
startTime = System.currentTimeMillis();
running = true;
return this;
}

public Stopwatch stop(){
stopTime = System.currentTimeMillis();
running = false;
return this;
}

public Stopwatch reset(){
startTime = -1;
stopTime = -1;
running = false;
return this;
}

public long getElapsedTime(){
if(startTime == -1)
return 0;
else if(running)
return System.currentTimeMillis() - startTime;
else
return stopTime - startTime;
}
}


Para poder utilizar esta clase sólo debemos crear una instancia, y llamar a los métodos necesarios.

Ejemplo:


public static void main(String[] args){
Stopwatch timer = new Stopwatch().start();
long total = 0;
for(int i = 0; i Integer.MAX_VALUE; i++){
total +=i;
}
System.out.println(timer.getElapsedTime());
}

Paso de Parámetros en java: Por Valor

Parámetros por Valor.

Se utiliza cuándo se requiere pasar el valor de una variable a una función y que está realize alguna operación sobre ese Valor, la función o método crea una Variable Local y trabaja sobre ella.

int a=5;
metodo(a):


void metodo(int c) {
 System.out.println(c);
}

La variable c, es una variable local y que recibe una copia del valor de la variable a, es decir se pasa el parámetro por valor.

Paso por Referencia.

El paso por referencia en vez de mandar el valor de la variable, se mánda la dirección de memoria en la que se encuentra almacenada, para de está manera modificar el contenido de la variable. Sin embargo este tipo de paso de parámetros en Java no existe pero si lo quisieramos hacer en C++ sería algo así:


include
using namespace std;

void funcion(int &a) {
 a = 10;
}


int main() {
 int var = 5;
 funcion(&var);
 cout <<>
}

El resultado de la ejecución sería, 10 ya que la variable 10 se pasa por referencia y la función modifica su valor.


Ahora regresando a lo importante ¿Cómo pasa los parámetros Java? En java sólo existe una forma de hacerlo y con el paso de parámetos por valor, aquí dejo un ejemplo de esto:

public class PasoPorValor {

 public static void main(String [] args) {
  int a = 20;
  metodo(a);
  System.out.println(a);

 }

 public static void metodo(int c) {
  c = 10;
 }

}

El valor de la variable a siempre es el mismo. Ahora veamos un ejemplo utilizando objetos, en este caso utilizaré un arreglo, ya que por definición los arreglos son objetos:

public class PasoPorValor {

 public static void main(String [] args) {
  int[] a = new int[1]; //declaramos un arreglo de una posición;
  metodo(a);
  System.out.println(a[0]);

 }

 public static void metodo(int[] c) {
  c[0] = 10;
 }


}

Pero que ocurrió!!! Por qué cambió el valor mi objeto? En realidad esto ocurre por la sencilla razón de que en Java las variables que apuntan a objetos, no son el objeto, sino una referencia al él, es decir en Java cuando hacemos esto:

int[] a = new int[1]; 

Estamos creando una referencia que tiene cómo identificador a y que el tipo de datos al que hace referencia es un arreglo de int y además ahí mismo con el operador new se crea el objeto, y por lo tanto la variable a, hará referencia a la locación de memoria de ese objeto.

Entonces cuándo el método recibe la referencia y lo modifica, estamos modificando el valor del objeto, pero ojo, esto no quiere decir que Java pase parámetros por referencia, sino que PASA EL VALOR DE LA REFERENCIA 

Si Java pasara valores por referencia cuándo hacemos esto:

public class PasoPorValor {

 public static void main(String [] args) {
  String a = "Hola";
  metodo(a);
  System.out.println(a);

 }

 public static void metodo(String c) {
  c = "Nuevo Objeto";
 }


}

El resultado debería ser "Nuevo Objeto" Sin embargo esto no sucede por la simple y sencilla razón de que Java sólo pasa parámetros por valor


Espero con esto quede un poco más claro cómo pasa los parámetros Java

Saludos