Category Archives: Java

Here Be Dragons

¡Por fin, la Víctoria! Ya soy todo un Caballero, con espada, escudo y armadura.

Después de dos semanas y nueve pruebas he logrado vencer al Dragón gracias a las armas que Atlassian proporciona: Jira, Confluence, Fisheye, Bonfire, Crucible y Bamboo. Utilizar la guía Here Be Dragons para instalar toda la suite integrada de productos, ha sido una forma amena, divertida y sobretodo muy útil, para ver qué se puede hacer con estas potentes herramientas y de qué forma pueden ayudar a una compañía a vencer al “dragón” que supone el día a día en el desarrollo de software: gestión de incidencias, peticiones, evolutivos, documentación, testing, integración de peticiones y documentación con repositorios de código, integración continua… y un sin fin de herramientas tan útiles como una espada, un escudo o una armadura.

¡Desde aquí os animamos a participar en el reto y ver qué os ofrece Atlassian!

Three useful or not… Java functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int heavy_decimal_count(int a, int b) {
    int result = 0;
    Hashtable<string, Double> range = new Hashtable<string, Double>();
 
    char[] number;
    double avg;
    for (int i = a; i < = b; i++) {
        number = String.valueOf(i).toCharArray();
 
        avg = 0.0;
	for(int j = 0; j < number.length; j++) {
	    avg += Integer.parseInt(String.valueOf(number[j]));
	}
 
        avg /= number.length;
	if (avg >= 7.25)
	    result++;
 
        range.put(String.copyValueOf(number), Double.valueOf(avg));
    }
 
    return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int dominator(int[] A) {
    int result = -1;
 
    Hashtable<string, Double> occurrence;
    Hashtable<integer, Hashtable<string, Double>> indexes = new Hashtable<integer, Hashtable<string, Double>>();
 
    for (int i = 0; i < A.length; i++) {
        if (indexes.containsKey(Integer.valueOf(A[i]))) {
            occurrence = indexes.get(Integer.valueOf(A[i]));
            occurrence.put("OCCURRENCES", occurrence.get("OCCURRENCES").doubleValue() + 1);
            occurrence.put("DOMINATOR", (occurrence.get("OCCURRENCES").doubleValue() + 1) / A.length);
            occurrence.put("LASTINDEX", Double.valueOf(i));
        } else {
            occurrence = new Hashtable<string, Double>();
            occurrence.put("OCCURRENCES", 1.0);
            occurrence.put("DOMINATOR", 1.0 / A.length);
            occurrence.put("LASTINDEX", Double.valueOf(i));
        }
        indexes.put(Integer.valueOf(A[i]), occurrence);
    }
 
    Iterator<hashtable<string, Double>> it = indexes.values().iterator();
    while (it.hasNext()) {
        occurrence = it.next();
	if (occurrence.get("DOMINATOR").doubleValue() > 0.5) {
            result = occurrence.get("LASTINDEX").intValue();
        }
    }
 
    return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int amplitude(int[] A) {
    int result = -1;
    int newVal = 0;
 
    for (int i = 0; i < A.length ; i++) {
        for (int j = 0; j < A.length; j++) {
            if (j == i)
                continue;
            newVal = Math.abs(A[i] - A[j]);
            if (newVal > result)
                result = newVal;
        }
    }
 
    return result;
}

Google libera Closure, la librería JavaScript detrás de Gmail y Gmaps

Leyendo los feeds de javaHispano me he encontrado esta noticia del pasado día 10 de Noviembre de 2009. Google utiliza Closure en sus aplicacions GMail y GMaps. Esta libreria está formada por un compilador que optimiza y comprime el codigo JavaScript (ademas de comprobar la sintaxis y errores varios), una librería para manipular DOM, comunicaciones con servidor, creación de animaciones, procesado de texto, etc.; en definitiva una librería para manipular UI. Y por ultimo, la gente de Googleplex, nos brinda un sistema de plantillas para automatizar la creación dinámica de HTML a través de Java y JavaScript.

Oracle y Sun Microsystems la pareja de moda

Podemos leer en casi cualquier sitio como al final Oracle ha comprado, finalmente,  Sun Microsystems, dando un giro inesperado a la historia que empezó con IBM al acecho de Sun. Según se puede leer en la pagina web oficial de Sun el valor de la compra asciende a unos 7.400 millones de dólares (precio por acción : 9,50 $).

Ahora queda esperar como afectara este nuevo escenario a la tecnología Java y sobretodo a los RDBMS de Oracle y Sun. Recordemos que no hace mucho Sun Microsystems compro a MySql, por lo que ahora Oracle y MySql son hermanastros.

Interfaces Comparator y Comparable (y III)

Ya hace más de dos meses que debería haber publicado este post pero como sabeis el tiempo es un bien escaso y entre unas cosas y otras no he podido preparar el código hasta ahora.

Bueno al código! En esta última parte utilizaremos el interfaz Comparator para crear clases específicas para ordenar. Siguiendo el hilo de los anteriores posts he creado una clase para ordenar Personas por edad y otra para ordenar por altura. Por si solas no tendrían mucho sentido pero al implementar Comparator podremos utilizarlas para fijar la ordenación en diferentes estructuras de datos como vectores, listas, etc.

La primera clase es OrdenarPersonaPorEdad y al implementar Comparator hay que implementar (o sobrecargar :-P) los métodos compare(…) y equals(…). Sobre este último comentar que según la documentación de Sun habría que comprobar que realmente los criterios de comparación son los mismos. Pero en la práctica únicamente se comprueba que se está utilizando el mismo objeto; this y obj hacen referencia al mismo objeto.

Como en la clase Persona se utilizó Integer para la edad y la altura, ahora únicamente deberemos utilizar el métode compareTo(..) de Integer, lo que simplifica el diseño y el ejemplo.

import java.util.Comparator;
 
public class OrdenarPersonaPorEdad implements Comparator {
    /**
      * Return a negative integer,
      * zero, or a positive integer as
      * this object is less than, equal to,
      * or greater than the specified object.
      */
    public int compare(Persona p1, Persona p2) {
        return p1.getEdad().compareTo(p2.getEdad());
    }
 
    public boolean equals(Object obj) {
        return this == obj;
    }
}

Aquí podemos ver el código para la clase que comparará por altura. Como apunte, si recordamos la segunda parte del artículo, dónde se multiplicaba por -1 el resultado de compareTo(..) para devolver el orden inverso, aquí podríamos utilizarlo de la misma forma.

import java.util.Comparator;
 
public class OrdenarPersonaPorAltura implements Comparator {
    /**
      * Return a negative integer,
      * zero, or a positive integer as
      * this object is less than, equal to,
      * or greater than the specified object.
      */
    public int compare(Persona p1, Persona p2) {
        return p1.getAltura().compareTo(p2.getAltura());
    }
 
    public boolean equals(Object obj) {
        return this == obj;
    }
}

Y como el código de la clase para probar los dos comparadores con un Vector.

import java.util.Vector;
import java.util.Iterator;
import java.util.Collections;
 
public class Test {
    /**
      * Main para probar la clase.
      */
    public static void main(String[] args) {
        // Franc
	Persona franc = new Persona("Franc", 38, 1.77);
	// Rosa
	Persona rosa = new Persona("Rosa", 29, 1.98);
	// Maite
	Persona maite = new Persona("Maite", 37, 1.78);
 
	// Creo una comunidad de personas.
	Vector miComunidad = new Vector();
	miComunidad.add(franc);
	miComunidad.add(rosa);
	miComunidad.add(maite);
 
	// Ordeno por edad la comunidad de personas.
	Collections.sort(miComunidad, new OrdenarPersonaPorEdad());
 
	// Ya se puede listar la comunidad ordenada por edad.
	Iterator personaIter = miComunidad.iterator();
	System.out.println("Comunidad ordenada por edad.");
	while (personaIter.hasNext())
	    System.out.println(personaIter.next());
 
        // Ordeno por altura la comunidad de personas.
	Collections.sort(miComunidad, new OrdenarPersonaPorAltura());
 
	// Ya se puede listar la comunidad ordenada por altura.
        personaIter = miComunidad.iterator();
	System.out.println("Comunidad ordenada por altura.");
	while (personaIter.hasNext())
	    System.out.println(personaIter.next());
    }
}

Resultado de la ejecución:

Comunidad ordenada por edad.
Me llamo Rosa, tengo 29 y mi altura es 1.98
Me llamo Maite, tengo 37 y mi altura es 1.78
Me llamo Franc, tengo 38 y mi altura es 1.77

Comunidad ordenada por altura.
Me llamo Franc, tengo 38 y mi altura es 1.77
Me llamo Maite, tengo 37 y mi altura es 1.78
Me llamo Rosa, tengo 29 y mi altura es 1.98

Como podéis ver el uso de Comparator simplifica en muchas ocasiones la tarea de ordenar un Vector (por ejemplo). Tener presente este interfaz, así como el interfaz Comparable, a la hora de diseñar una aplicación puede ahorrar mucho código y simplificar futuras modificaciones, mejoras, etc.

Espero que esta serie de artículos sobre los interfaces de comparación que ofrece Java os halla gustado y os ayude en el futuro.

Interfaces Comparator y Comparable (II)

Lo prometido es deuda y ahora que tengo un slot libre de tiempo aquí tenéis el ejemplo que ilustra la primera parte de éste artículo. Podréis observar que al implementar el interfaz Comparable mediante la sobrecarga o implementación, del método abstracto (ver comentarios), compareTo(…) se ha utilizado el mismo método que proporciona Integer. De forma similar se hubiera podido implementar cualquier comparación devolviendo los valores indicados, en el “contrato” de la interfaz, según nuestro propio criterio. En este caso se ha modificado el valor devuelto, multiplicándolo por -1, para obtener la ordenación inversa, tal y como lo mencionó ‘jsanca’ en el comentario a la primera parte publicada también el DebugModeOn.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import java.util.Vector;
import java.util.Iterator;
import java.util.Collections;
 
public class Persona implements Comparable<persona> {
	private String miNombre;
	private Integer miEdad;
	private Float miAltura;
 
	public Persona(String nombre, int edad, double altura) {
		this.miNombre = new String(nombre);
		this.miEdad = new Integer(edad);
		this.miAltura = new Float(altura);
	}
 
	/**
	 * Return a negative integer,
	 * zero, or a positive integer as
	 * this object is less than, equal to,
	 * or greater than the specified object.
	 */
	public int compareTo(Persona per) {
		// Multiplicamos por -1 para obtener la ordenación
		// inversa como apuntó 'jsanca' en su comentario.
		return this.miEdad.compareTo(per.getEdad()) * -1;
	}
 
	public Integer getEdad() {
		return miEdad;
	}
 
	public void setEdad(int edad) {
		this.miEdad = new Integer(edad);
	}
 
	public Float getAltura() {
		return miAltura;
	}
 
	public void setAltura(double altura) {
		this.miAltura = new Float(altura);
	}
 
	public String toString() {
		StringBuffer result = new StringBuffer();
		result.append("Me llamo " + this.miNombre);
		result.append(", tengo " + this.miEdad);
		result.append(" y mi altura es " + this.miAltura);
		return result.toString();
	}
 
	/**
	 * Main para probar la clase.
	 */
	public static void main(String[] args) {
		// Franc
		Persona franc = new Persona("Franc", 38, 1.78);
		// Rosa
		Persona rosa = new Persona("Rosa", 29, 1.67);
		// Maite
		Persona maite = new Persona("Maite", 37, 1.98);
 
		// Creo una comunidad de personas.
		Vector miComunidad = new Vector();
		miComunidad.add(franc);
		miComunidad.add(rosa);
		miComunidad.add(maite);
 
		// Ordeno por edad la comunidad de personas.
		Collections.sort(miComunidad);
 
		// Ya se puede listar la comunidad ordenada.
		Iterator personaIter = miComunidad.iterator();
		System.out.println("Comunidad ordenada por edad.");
		while (personaIter.hasNext())
			System.out.println(personaIter.next());
	}
}

El resultado de la ejecución es el siguiente:
Mi comunidad ordenada por edad.
Me llamo Franc, tengo 38 y mi altura es 1.78
Me llamo Maite, tengo 37 y mi altura es 1.98
Me llamo Rosa, tengo 29 y mi altura es 1.67

Nos vemos en la próxima y última parte donde comentaré el uso de la interfaz Comparator.

Interfaces Comparator y Comparable (I)

Es posible que en ocasiones nos veamos obligados a ordenar o comparar clases que nosotros hemos implementado y que bien no pueden seguir unos criterios de comparación triviales. Por ejemplo al implementar la clase Persona y añadir n instancias en un vector, quizás aparezca la necesidad de ordenar dicho arreglo de personas. Está claro que recorriendo el vector y moviendo los objetos aplicando nuestro propio criterio se lograría el fin. Pero también es interesante conocer otras opciones. Si la elección de la plataforma y el lenguaje es Java, la implementación de la interfaz Comparable en la clase Persona es la forma más limpia, elegante y reusable para poder aplicar posteriormente una comparación entre objetos Persona. Para cumplir con el contrato de la interfaz únicamente estamos obligados a implementar el método:

public int compareTo(Object obj) throws ClassCastException;

dónde se debe devolver un valor negativo (-1) si nuestra instancia es menor que la instancia obtenida por parámetro, cero (0) si ambas instancias son iguales y un valor positivo mayor que cero (1) si nuestra instancia es mayor que la obtenida por parámetro. De igual manera se debería lanzar una excepción si la instancia obtenida por parámetro no es una instancia de la clase implementada.

Al implementar este método a la clase Persona, es posible ordenar y comparar objetos Persona que se encuentren en contenedores como Vector, Stack, TreeSet, etc. o en un vector de Personas (Persona[]). A diferencia de clases como TreeSet que ya ordena al añadir objetos, cuando se quiera obtener un objeto Vector, Stack, etc. o un vector ordenado, utilizaremos el método de clase Collections.sort(..), y volià al contenedor se le aplicará una ordenación siguiendo el método de ordenación implementado para Persona, que bien podría aplicarse a la edad, altura, peso, etc.

En el siguiente post (de ésta serie) y a través de un ejemplo, se mostrará lo explicado y los resultados obtenidos así como una introducción a la interfaz Comparator.

Ropes for Java

Acabo de leer en JavaHispano un interesante post sobre una implementación alternativa de las tradicionales cadenas de carácteres; Strings, para Java. Los llamados Ropes. La idea no es precisamente nueva (artículo de 1995) y trata de modificar la implementación mediante arrays de tamaño fijo, lo que da lugar a que sean objetos o tipos inmutables. La idea de los Ropes, es implementar mediante un árbol para logra una complejidad logarítmica en lugar de la dispuesta por Strings o StringsBuffers que puede llegar a ser cuadrática. Según el artículo (y coincido con él), el problema es que la implementación mediante un árbol es muy cara en términos de memoria.