<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>El Blog de Ana Buigues &#187; Java</title>
	<atom:link href="http://anabuigues.com/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://anabuigues.com</link>
	<description></description>
	<lastBuildDate>Wed, 07 Dec 2011 16:07:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Cómo configurar Hibernate sin ningún xml</title>
		<link>http://anabuigues.com/2011/02/07/como-configurar-hibernate-sin-ningun-xml/</link>
		<comments>http://anabuigues.com/2011/02/07/como-configurar-hibernate-sin-ningun-xml/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 17:56:12 +0000</pubDate>
		<dc:creator>Ana Buigues</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[JPA]]></category>
		<guid isPermaLink="false">http://anabuigues.com/?p=3359</guid>
		<description><![CDATA[Realizar la configuración de Hibernate con ficheros xml puede llegar a ser bastante engorroso, especialmente en aplicaciones muy grandes. Afortunadamente podemos inicializar la unidad de persistencia de forma programática y realizar los mapeos de las entidades mediante anotaciones, de esta forma conseguimos no tener que utilizar ningún fichero xml para la configuración. A continuación un [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Realizar la configuración de <strong>Hibernate</strong> con ficheros xml puede llegar a ser bastante engorroso, especialmente en aplicaciones muy grandes. Afortunadamente podemos <strong>inicializar la unidad de persistencia de forma programática </strong>y realizar los mapeos de las entidades mediante anotaciones, de esta forma conseguimos no tener que utilizar ningún fichero xml para la configuración.</p>
<p style="text-align: justify;">A continuación un ejemplo de cómo hacerlo.</p>
<p style="text-align: justify;"><span id="more-3359"></span></p>
<h2 style="text-align: justify;">Creación de la unidad de persistencia:</h2>
<pre class="brush: java; title: ; notranslate">
public class PersistenceUnitStarter {
	//Añadimos las propiedades que queramos a la unidad de persistencia
	private static Properties getProperties() {
		Properties properties = new Properties();
		properties.setProperty(Environment.DRIVER, &quot;org.h2.Driver&quot;);
		properties.setProperty(Environment.URL,
				&quot;jdbc:h2:db;LOG=0;CACHE_SIZE=65536;LOCK_MODE=0;UNDO_LOG=0&quot;);
		properties.setProperty(Environment.USER, &quot;&quot;);
		properties.setProperty(Environment.PASS, &quot;&quot;);
		properties.put(Environment.SHOW_SQL, &quot;true&quot;);
		properties.put(Environment.FORMAT_SQL, &quot;true&quot;);
		properties.put(Environment.FLUSH_BEFORE_COMPLETION, &quot;false&quot;);
		properties.put(Environment.TRANSACTION_STRATEGY,
				PersistenceUnitTransactionType.RESOURCE_LOCAL);
		properties.put(Environment.HBM2DDL_AUTO, &quot;create&quot;);
		return properties;
	}
        //Le pasamos una lista con las clases que queremos añadir a la entidad de persistencia
        //Las clases tienen que estar definidas con anotaciones
	public static EntityManagerFactory createPersistenceUnit(List&lt;Class&gt; entities) {
		Ejb3Configuration conf = new Ejb3Configuration();
		conf.addProperties(getProperties());
		//añadimos los entities declarados con anotaciones
		for (Class clazz : entities) {
			conf.addAnnotatedClass(clazz);
		}
		return conf.buildEntityManagerFactory();
	}
}
</pre>
<h2>Creamos las entidades mediante anotaciones</h2>
<pre class="brush: java; title: ; notranslate">
@Entity
public class Persona {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	@Column(nullable = false)
	private String nombre;
	@Column(nullable = false)
	private String apellido;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getNombre() {
		return nombre;
	}
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	public String getApellido() {
		return apellido;
	}
	public void setApellido(String apellido) {
		this.apellido = apellido;
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://anabuigues.com/2011/02/07/como-configurar-hibernate-sin-ningun-xml/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mi primera Code Kata</title>
		<link>http://anabuigues.com/2011/02/01/mi-primera-code-kata/</link>
		<comments>http://anabuigues.com/2011/02/01/mi-primera-code-kata/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 17:40:00 +0000</pubDate>
		<dc:creator>Ana Buigues</dc:creator>
				<category><![CDATA[Code Kata]]></category>
		<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[12meses12katas]]></category>
		<guid isPermaLink="false">http://anabuigues.com/?p=3344</guid>
		<description><![CDATA[Ayer hice junto a Héctor Rodes mi primera Code Kata, gracias a la iniciativa de 12meses12katas, donde cada mes se propone una nueva kata. Abierta a todo el mundo y a todos los lenguajes de programación, excelente para poder practicar y aprender. Y&#8230;¿qué es una Code Kata? pues una Code Kata hace referencia a un ejercicio de programación en [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://anabuigues.com/wp-content/uploads/2011/02/code_kata.png"><img class="alignleft size-full wp-image-3355" title="code_kata" src="http://anabuigues.com/wp-content/uploads/2011/02/code_kata.png" alt="" width="151" height="202" /></a>Ayer hice junto a <a href="http://hectorrodes.com" target="_blank">Héctor Rodes</a> mi primera <strong>Code Kata</strong>, gracias a la iniciativa de <a href="http://12meses12katas.com/" target="_blank">12meses12katas</a>, donde cada mes se propone una nueva <strong>kata</strong>. Abierta a todo el mundo y a todos los lenguajes de programación, excelente para poder practicar y aprender.</p>
<p style="text-align: justify;">Y&#8230;¿qué es una <strong>Code Kata</strong>? pues una <a href="http://en.wikipedia.org/wiki/Kata_(programming)" target="_blank">Code Kata</a> hace referencia a un ejercicio de programación en el cual se resuelve un problema más o menos complejo donde el objetivo es mejorar las cualidades de un programador mediante la práctica y resolución repetitiva de problemas.</p>
<p style="text-align: justify;">Lo que obtenemos de todo esto es obligarnos a encontrar una solución a un problema y además nos permite contrastar nuestra solución con la de otras personas, de esta forma podemos descubrir nuevas formas de resolver el mismo problema, y si la <a href="http://en.wikipedia.org/wiki/Pair_programming" target="_blank">programas en parejas</a> es todavía más divertido.</p>
<p style="text-align: justify;"><span id="more-3344"></span></p>
<p style="text-align: justify;">Para Enero el ejercicio de la <strong>Code Kata </strong>era el<strong> String Calculator</strong>, la idea es hacer un programa que sume  los números de una cadena separados por diferentes delimitadores, por ejemplo: &#8220;8*5%3&#8243; . Si queréis ver el código de la gente que ha realizado la <strong>Code Kata</strong> podéis visitar el <a href="https://github.com/12meses12katas/Enero-String-Calculator" target="_blank">github del proyecto</a>. El nuestro está en el directorio de animalaes.</p>
<h3 style="text-align: justify;">Nuestra solución</h3>
<p style="text-align: justify;">La hemos realizado en Java, con la ayuda de la clase Scanner de Java para parsear la cadena mediante expresiones regulares. Se admiten sugerencias sobre mejoras o lo que sea.</p>
<pre class="brush: java; title: ; notranslate">
package com.anabuigues;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;
/**
 * Implementación sencilla de la calculadora para la kata de enero.&lt;br /&gt;
 * &lt;br /&gt;
 * La implementación está realizada usando java 6 estándar apoyándose en la
 * clase Scanner que permite trocear al vuelo un imput a partir de un o n
 * delimitadores. Para ello extrae los delimitadores y construye una expresión
 * reguar válida para el scanner al que se le solicitan los diferentes enteros
 * para ir sumándolos.
 *
 *
 * @author A. Buigues (@animalaes), H. Rodes (@hector_rodes)
 *
 */
public class StringCalculator {
	public int add(String numbers) throws Exception {
		int returnValue;
		if (numbers == null || numbers.isEmpty()) {
			returnValue = 0;
		} else {
			ByteArrayInputStream bais = new ByteArrayInputStream(
					numbers.getBytes());
			Scanner sc = new Scanner(bais);
			String delimiters = null;
			// Delimiters
			if (numbers.startsWith(&quot;//&quot;)) {
				sc.useDelimiter(&quot;//|\n&quot;);
				if (sc.hasNext()) {
					delimiters = sc.next();
				}
			}
			delimiters = getScannerFormattedDelimiters(delimiters);
			// Process number lines with numbers to be added
			sc.useDelimiter(delimiters);
			int sum = 0;
			int currentNumber;
			List&lt;Integer&gt; negativeValues = new ArrayList&lt;Integer&gt;();
			while (sc.hasNext()) {
				currentNumber = sc.nextInt();
				if (currentNumber &lt; 0) {
					negativeValues.add(currentNumber);
				} else if (currentNumber &lt;= 1000) {
					sum += currentNumber;
				}
			}
			checkNegativeValues(negativeValues);
			returnValue = sum;
		}
		return returnValue;
	}
	/**
	 * Método auxiliar que comprueba si hay números negativos y forma el mensaje
	 *
	 * @param negativeValues
	 *            Lista de números negativos
	 * @throws Exception
	 *             Si la lista de números negativos contiene algún número
	 */
	private void checkNegativeValues(List&lt;Integer&gt; negativeValues)
			throws Exception {
		if (negativeValues != null &amp;&amp; negativeValues.size() &gt; 0) {
			StringBuilder sb = new StringBuilder(&quot;negatives not allowed&quot;);
			for (int negative : negativeValues) {
				sb.append(&quot; &quot;).append(negative);
			}
			throw new Exception(sb.toString());
		}
	}
	/**
	 * Genera la cadena de delimitadores necesaria para ser usada en el scanner
	 * y así poder procesar los números.&lt;br /&gt;
	 * Siempre introduce el \n como un delimitador válido.&lt;br /&gt;
	 * En caso de que los delimiters sean vacÌos o nulos usa la , y el \n como
	 * delimitadores por defecto
	 *
	 * @param delimiters
	 *            Los delimitadores introducidos
	 * @return Cadena con los delimitadores en el formato que espera el Scanner
	 */
	private String getScannerFormattedDelimiters(String delimiters) {
		String delimitersExpression;
		if (delimiters == null || delimiters.isEmpty()) {
			delimitersExpression = &quot;,|\n&quot;;
		} else {
			String currentDelimiter;
			StringBuilder sb = new StringBuilder();
			Scanner scDelimiters = new Scanner(delimiters).useDelimiter(Pattern
					.quote(&quot;]&quot;) + &quot;|&quot; + Pattern.quote(&quot;[&quot;));
			while (scDelimiters.hasNext()) {
				currentDelimiter = scDelimiters.next();
				if (!currentDelimiter.isEmpty()) {
					sb.append(Pattern.quote(currentDelimiter)).append(&quot;|&quot;);
				}
			}
			sb.append(&quot;\n&quot;);
			delimitersExpression = sb.toString();
		}
		return delimitersExpression;
	}
}
</pre>
<p>Y su test</p>
<pre class="brush: java; title: ; notranslate">
package com.anabuigues;
import junit.framework.Assert;
import org.junit.Test;
/**
 *
 * @author A. Buigues (@animalaes), H. Rodes (@hector_rodes)
 *
 */
public class CalculatorTest {
	private StringCalculator calculator = new StringCalculator();
	@Test
	public void basicCalculator() throws Exception {
		Assert.assertEquals(0, calculator.add(&quot;&quot;));
		Assert.assertEquals(1, calculator.add(&quot;1&quot;));
		Assert.assertEquals(10, calculator.add(&quot;7,3&quot;));
		Assert.assertEquals(10, calculator.add(&quot;7\n2,1&quot;));
		Assert.assertEquals(27, calculator.add(&quot;5\n5\n8,2,4\n2,1&quot;));
	}
	@Test
	public void simpleDelimiterCalculator() throws Exception {
		Assert.assertEquals(16, calculator.add(&quot;//[*]\n5*5*6&quot;));
		Assert.assertEquals(20, calculator.add(&quot;//[*]\n5*5*6\n4&quot;));
		Assert.assertEquals(20, calculator.add(&quot;//[*][;][,]\n5,5;6\n4&quot;));
		Assert.assertEquals(20,
				calculator.add(&quot;//[*][;][pollofrito]\n5pollofrito5;6\n4&quot;));
	}
	@Test
	public void bigNumbersCalculator() throws Exception {
		Assert.assertEquals(1005, calculator.add(&quot;//[*]\n5*1000*1001&quot;));
	}
	@Test
	public void negativeNumbersCalculator() throws Exception {
		try {
			Assert.assertEquals(1005, calculator.add(&quot;//[*]\n5*-23*45*-34&quot;));
		} catch (Exception e) {
			Assert.assertTrue(&quot;-23 must be in error message &quot;, e.getMessage()
					.indexOf(&quot;-23&quot;) != -1);
			Assert.assertTrue(&quot;-34 must be in error message &quot;, e.getMessage()
					.indexOf(&quot;-34&quot;) != -1);
		}
	}
	@Test
	public void notDefinedDelimiterCalculator() throws Exception {
		try {
			Assert.assertEquals(8, calculator.add(&quot;//[*]\n5;3&quot;));
			Assert.fail(&quot;Delimiter ; is not allowed but it has been used&quot;);
		} catch (Exception e) {
		}
	}
}
</pre>
<p style="text-align: justify;">Ahora toca ponerse con la de febrero!!</p>
<p style="text-align: justify;">
]]></content:encoded>
			<wfw:commentRss>http://anabuigues.com/2011/02/01/mi-primera-code-kata/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Comparator vs Comparable en Java</title>
		<link>http://anabuigues.com/2010/09/17/comparator-vs-comparable-en-java/</link>
		<comments>http://anabuigues.com/2010/09/17/comparator-vs-comparable-en-java/#comments</comments>
		<pubDate>Fri, 17 Sep 2010 16:17:12 +0000</pubDate>
		<dc:creator>Ana Buigues</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Comparable]]></category>
		<category><![CDATA[Comparator]]></category>
		<guid isPermaLink="false">http://anabuigues.com/?p=1145</guid>
		<description><![CDATA[Diferencia entre Comparable y Comparator La diferencia principal entre Comparable y Comparator es que Comparable es utilizado para implementar el orden natural, sin necesidad de especificar un Comparator, por ejemplo, los String son comparados alfabéticamente. Usamos Comparator cuando queramos crear otro tipo de orden que no sea el natural. El contrato que implica implementar Comparable [...]]]></description>
			<content:encoded><![CDATA[<h2 style="text-align: justify;">Diferencia entre Comparable y Comparator</h2>
<p style="text-align: justify;">La diferencia principal entre <strong><span style="font-family: andale mono,times;">Comparable</span></strong> y <strong><span style="font-family: andale mono,times;">Comparator</span></strong> es que <strong><span style="font-family: andale mono,times;">Comparable</span></strong> es utilizado para implementar el orden natural, sin necesidad de especificar un <strong><span style="font-family: andale mono,times;">Comparator</span></strong>, por ejemplo, los <strong><span style="font-family: andale mono,times;">String</span></strong> son comparados alfabéticamente. Usamos <strong><span style="font-family: andale mono,times;">Comparator</span></strong> cuando queramos crear otro tipo de orden que no sea el natural.</p>
<p style="text-align: justify;">El contrato que implica implementar <strong><span style="font-family: andale mono,times;">Comparable</span></strong> requiere de un parámetro extra, el objeto con el que comparar <strong><span style="font-family: andale mono,times;">compareTo(obj1)</span></strong> de forma que la comparación se realizará del objeto en si (<strong><span style="font-family: andale mono,times;">this</span></strong>) con el objeto pasado como parámetro. <strong><span style="font-family: andale mono,times;">Comparator</span></strong>, sin embargo obliga a implementar el método <strong><span style="font-family: andale mono,times;">compare (obj1, obj2)</span></strong> de forma que los dos objetos a comparar son pasados como parámetros y el objeto que implementa el método <strong><span style="font-family: andale mono,times;">compare</span></strong> simplemente sirve de apoyo a la comparación.</p>
<p style="text-align: justify;"><span id="more-1145"></span></p>
<h2>Sobreescritura de los métodos <span style="font-family: andale mono,times;">compareTo</span> y <span style="font-family: andale mono,times;">compare</span></h2>
<p style="text-align: justify;">La forma de sobreescribir estos métodos es muy similar al <a href="http://anabuigues.com/2010/07/06/como-sobreescribir-los-metodos-equals-y-hashcode-de-java/" target="_blank"><strong><span style="font-family: andale mono,times;">equals</span></strong></a>. Los dos métodos cumplen las mismas restricciones que podemos objtener del API de Java:</p>
<ul style="text-align: justify;">
<li>Devolvemos un <strong>número negativo</strong> si el objeto es <strong>menor</strong>, devolvemos un <strong>cero</strong> si es <strong>igual</strong> y un<strong> número positivo</strong> si el objeto es <strong>mayor.</strong></li>
<li>Comparamos el objeto con otro objeto del mismo tipo. Si no son del mismo tipo, lanzamos un <strong>ClassCastException.</strong></li>
</ul>
<p style="text-align: justify;">La notación <strong>sgn</strong>(expresion) es la función matemática signum, la cual devuelve -1,0, o 1  según sea negativo, zero o positivo</p>
<ul>
<li>Debemos asegurar que:<strong> sgn(compare(x,y)) == -sgn(compare(x,y))</strong>, para todo <strong>x, y</strong>. Esto implica que <strong>compare(x,y))</strong> lanzará una excepción sii <strong>compare(x,y)</strong> también la lanza.</li>
</ul>
<ul>
<li>Debemos asegurar que la relación es transitiva:<strong> compare(x,y) &gt; 0 &amp;&amp; compare(y,z) &gt; 0 </strong>implica que <strong>compare(x,z) &gt; 0</strong></li>
</ul>
<ul>
<li>Debemos asegurar que:<strong> compare(x,y) == 0 </strong>implica que<strong> sgn(compare(x,z)) == sgn(compare(y,z))</strong>, para todo <strong>z.</strong></li>
</ul>
<ul>
<li style="text-align: justify;">Se recomienda, aunque no es estrictamente neceario, nos puede evitar poblemas al usar colecciones que implementen esta interfaz.<strong> (compare(x,y) == 0) == (x.equals(y))</strong></li>
</ul>
<ul>
<li style="text-align: justify;">El orden natural para una clase &#8220;c&#8221;  tiene que ser consistente con el equals si y solo sí:<strong> compare(e1,e2) == 0</strong> tiene que ser el mismo resultado que para <strong>e1.equals(e2) </strong>para cada <strong>e1</strong> y <strong>e2</strong> de la clase &#8220;c&#8221;.</li>
</ul>
<h2>Uso de Comparable y Comparator</h2>
<p style="text-align: justify;">Podemos usarlos en listas y arrays mediante los métodos <strong>Collections.sort</strong> y <strong>Arrays.sort</strong>.También como claves en un mapa ordenado <strong>TreeMap</strong> o como elementos en un set ordenado <strong>TreeSet</strong>.</p>
<p style="text-align: justify;">En el caso de Comparable los objetos tienen que implementar esta interfaz para que los ordene automáticamente. Para el caso del Comparator debemos especificar el Comparator.</p>
<h2>Ejemplo Comparable</h2>
<pre class="brush: java; title: ; notranslate">
//Ejemplo Comparable
public class Person implements Comparable&lt;Person&gt; {
 private String firstName;
 private String lastName;
 public Person(String firstName, String lastName) {
  if (firstName == null || lastName == null)
   throw new NullPointerException();
  this.firstName = firstName;
  this.lastName = lastName;
 }
 @Override
 public String toString() {
  return String.format(&quot;%s, %s&quot;, firstName, lastName);
 }
 @Override
 public int compareTo(Person p) {
  int lastCmp = firstName.compareTo(p.firstName);
  return (lastCmp != 0 ? lastCmp : lastName.compareTo(p.lastName));
 }
 public static void main(String[] args) {
  Set&lt;Person&gt; p = new TreeSet&lt;Person&gt;();
  p.add(new Person(&quot;Ana&quot;, &quot;Rodes&quot;));
  p.add(new Person(&quot;Hector&quot;, &quot;Lopez&quot;));
  p.add(new Person(&quot;Ana&quot;, &quot;Buigues&quot;));
  p.add(new Person(&quot;Carlitos&quot;, &quot;Perez&quot;));
  for (Person person : p)
   System.out.println(person);
 }
}
</pre>
<p>La salida será:<br />
Ana, Buigues<br />
Ana, Rodes<br />
Carlitos, Perez<br />
Hector, Lopez</p>
<h2>Ejemplos Comparator</h2>
<pre class="brush: java; title: ; notranslate">
//Ejemplo Comparator
public class LengthComparator implements Comparator&lt;Person&gt; {
 @Override
 public int compare(Person p1, Person p2) {
  if (p1.toString().length() &lt; p2.toString().length())
   return 1;
  else if (p1.toString().length() &gt; p2.toString().length())
   return -1;
  else
   return 0;
 }
 public static void main(String[] args) {
  List&lt;Person&gt; p = new ArrayList&lt;Person&gt;();
  p.add(new Person(&quot;Ana&quot;, &quot;Rodes&quot;));
  p.add(new Person(&quot;Hector&quot;, &quot;Lopez&quot;));
  p.add(new Person(&quot;Ana&quot;, &quot;Buigues&quot;));
  p.add(new Person(&quot;Carlitos&quot;, &quot;Perez&quot;));
  Collections.sort(p, new LengthComparator());
  for (Person person : p)
   System.out.println(person);
 }
}
</pre>
<p>La salida será:<br />
Ana, Rodes<br />
Ana, Buigues<br />
Hector, Lopez<br />
Carlitos, Perez</p>
<p>También lo podemos utilizar de forma anónima</p>
<pre class="brush: java; title: ; notranslate">
Set&lt;Person&gt; persons = new TreeSet&lt;Person&gt;(new Comparator&lt;Person&gt;() {
  @Override
 public int compare(Person p1, Person p2) {
  if (p1.toString().length() &lt; p2.toString().length())
   return 1;
  else if (p1.toString().length() &gt; p2.toString().length())
   return -1;
  else
   return 0;
 }
});
</pre>
]]></content:encoded>
			<wfw:commentRss>http://anabuigues.com/2010/09/17/comparator-vs-comparable-en-java/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Cómo sobreescribir los métodos equals y hashCode de Java</title>
		<link>http://anabuigues.com/2010/07/06/como-sobreescribir-los-metodos-equals-y-hashcode-de-java/</link>
		<comments>http://anabuigues.com/2010/07/06/como-sobreescribir-los-metodos-equals-y-hashcode-de-java/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 20:18:23 +0000</pubDate>
		<dc:creator>Ana Buigues</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[equals]]></category>
		<category><![CDATA[hashCode]]></category>
		<guid isPermaLink="false">http://anabuigues.com/?p=1051</guid>
		<description><![CDATA[En la clase java.lang.Object (y por lo tanto, por herencia, en todas las demás clases) tenemos métodos que a veces olvidamos y que son importantes: public boolean equals(Object o) public int hashCode() Estos métodos son especialmente importantes si vamos a guardar nuestros objetos en cualquier tipo de colección: listas, mapas&#8230; y más aun si los [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">En la clase<span style="font-family: andale mono,times;"> <code>java.lang.Object</code></span> (y por lo tanto, por herencia, en todas las demás clases) tenemos métodos que a veces olvidamos y que son importantes:</p>
<ul style="text-align: justify;">
<li><span style="font-family: courier new,courier;"><strong>public boolean equals(Object o)</strong></span></li>
<li><span style="font-family: courier new,courier;"><strong>public int hashCode()</strong></span></li>
</ul>
<p style="text-align: justify;">Estos métodos son especialmente importantes si vamos a guardar nuestros objetos en cualquier tipo de colección: listas, mapas&#8230; y más aun si los objetos que vamos a guardar en la colección son serializables.</p>
<p style="text-align: justify;">Estos métodos tienen formas explicitas de cómo hay que implementarlos. Sobreescribir estos métodos puede parecer simple, pero en realidad hay muchas formas de hacerlo incorrectamente lo que nos puede llevar a muchos crebraderos de cabeza. Lo vemos a continuación.</p>
<p style="text-align: justify;"><span id="more-1051"></span></p>
<h2 style="text-align: justify;">Sobreescribir el método <span style="font-family: courier new,courier;"><strong>equals</strong></span></h2>
<p style="text-align: justify;">Cuando sobreescribimos el método <span style="font-family: courier new,courier;"><strong>equals</strong></span> tenemos que tener en cuenta lo que se especifica en el <a href="http://java.sun.com/javase/6/docs/api/java/lang/Object.html" target="_blank">API de Java para Object</a> sobre este método. Debe cumplir las siguientes propiedades:</p>
<ul style="text-align: justify;">
<li><strong>Reflexiva:</strong> para cualquier referencia no nula para un valor <strong><span style="font-family: andale mono,times;">x</span>, <span style="font-family: andale mono,times;">x.equals(x)</span> </strong>debe devolver <strong><span style="font-family: andale mono,times;">true</span></strong>.</li>
<li><strong>Simétrica: </strong>para cualquier referencia no nula para valores <strong><span style="font-family: andale mono,times;">x</span> e <span style="font-family: andale mono,times;">y</span>, <span style="font-family: andale mono,times;">x.equals(y) </span></strong>debe devolver <strong><span style="font-family: andale mono,times;">true</span> sii <span style="font-family: andale mono,times;">y.equals(x) </span></strong>devuelve <strong><span style="font-family: andale mono,times;">true</span></strong>.</li>
<li><strong>Transitiva:</strong> para cualquier referencia no nula para valores <strong><span style="font-family: andale mono,times;">x</span>, <span style="font-family: andale mono,times;">y</span>,<span style="font-family: andale mono,times;">z</span>, si <span style="font-family: andale mono,times;">x.equals(y)</span> </strong>devuelve <strong><span style="font-family: andale mono,times;">true</span></strong> y <strong><span style="font-family: andale mono,times;">y.equals(z) </span></strong>devuelve <strong><span style="font-family: andale mono,times;">true</span></strong>, entonces <span style="font-family: andale mono,times;"><strong>x.equals(z)</strong> </span>debe devolver <strong><span style="font-family: andale mono,times;">true</span></strong>.</li>
<li><strong>Consistente:</strong> para cualquier referencia no nula para valores <strong><span style="font-family: andale mono,times;">x</span> e <span style="font-family: andale mono,times;">y</span>, múltiples llamadas al método <span style="font-family: andale mono,times;">x.equals(y) </span></strong>deben consistentemente <strong>devolver siempre <span style="font-family: andale mono,times;">true</span> o consistentemente devolver <span style="font-family: andale mono,times;">false</span></strong>. Siempre y cuando no se modifique la información usada en las comparaciones.</li>
<li style="text-align: justify;"><strong>No nulo:</strong> para cualquier referencia no nula para un valor <strong><span style="font-family: andale mono,times;">x</span>, <span style="font-family: andale mono,times;">x.equals(null)</span></strong> debe devolver <strong><span style="font-family: andale mono,times;">false</span></strong>.</li>
</ul>
<p style="text-align: justify;">Ahora que sabemos lo que tiene que cumplir, vamos a ver que pasos podemos seguir para su implementación:</p>
<ul style="text-align: justify;">
<li style="text-align: justify;">Usamos el operador <span style="font-family: courier new,courier;">==</span> para comprobar si el argumento es una referencia al mismo objeto.</li>
<li style="text-align: justify;">Usamos el operador <span style="font-family: courier new,courier;">instanceof</span> para comprobar si el argumento es un objeto de nuestra clase.</li>
<li style="text-align: justify;">Hacemos un cast del argumento al nuestro objeto. Ya sabemos que es una instancia de nuestro objeto, por el paso anterior.</li>
<li style="text-align: justify;">Para cada campo significativo de nuestro objeto, comprobamos que se corresponda con el que se pasa como argumento. Primero comprobamos los tipos primitivos y luego los más complejos. Para los tipos <span style="font-family: courier new,courier;">Float</span> y <span style="font-family: courier new,courier;">Double</span>, usamos los métodos <span style="font-family: courier new,courier;">Float.Compare</span> y <span style="font-family: courier new,courier;">Double.Compare.</span> Para el tipo <span style="font-family: courier new,courier;">String</span>, usamos el equals del string. Para comparar arrays usamos <span style="font-family: courier new,courier;">Arrays.equals</span>. Tenemos que tener en cuenta que los campos pueden contener referencias a <span style="font-family: courier new,courier;">null</span>. No debemos incluir campos que tengan que ver con el estado de un objeto, como por ejemplo tipos <span style="font-family: andale mono,times;">Lock</span>. Tampoco tenemos que incluir campos que sean cálculos de otros campos, es redundante.</li>
<li style="text-align: justify;">Cuando terminemos, tenemos que preguntarnos: ¿es reflexivo?, ¿es simétrico?, ¿es transitivo?, ¿es consistente? y ¿no nullo?</li>
</ul>
<pre class="brush: java; title: ; notranslate">
//Ejemplo de cómo sobreescribir el método equals()
public class Casa {
 private int num;
 private String direccion;
 private double precio;
 private List&lt;Propietario&gt; prop;
 public Casa(int num, String direccion, double precio,
            List&lt;Propietario&gt; prop) {
  this.num = num;
  this.direccion = direccion;
  this.precio = precio;
  this.prop = prop;
 }
 @Override
 public boolean equals(Object o) {
  if (o == null)
   return false;
  if (o == this)
   return true;
  if (!(o instanceof Casa))
   return false;
  Casa c = (Casa) o;
  if (num != c.num)
   return false;
  if (direccion == null || !direccion.equals(c.direccion))
   return false;
  if (Double.compare(precio, c.precio) != 0)
   return false;
  if (prop != c.prop &amp;&amp; (prop == null || !prop.equals(c.prop)))
   return false;
 return true;
 }
}
public class Propietario {
 private String nombre;
 private String apellidos;
 private int num;
 public Propietario(String nombre, String apellidos, int num) {
  this.nombre = nombre;
  this.apellidos = apellidos;
  this.num = num;
 }
 @Override
 public boolean equals(Object o) {
  if (o == null)
   return false;
  if (o == this)
   return true;
  if (!(o instanceof Propietario))
   return false;
  Propietario p = (Propietario) o;
  if ((nombre == null) ? (p.nombre != null) : !nombre.equals(p.nombre))
    return false;
  if ((apellidos == null) ? (p.apellidos != null) :
     !apellidos.equals(p.apellidos))
    return false;
  if (num != p.num)
    return false;
  return true;
 }
}
</pre>
<h2>Sobreescribir el método <span style="font-family: courier new,courier;"><strong>hashCode</strong></span></h2>
<p style="text-align: justify;">Siempre que sobreescribamos el método <span style="font-family: courier new,courier;"><strong>equals</strong></span>, también tenemos que sobreescribir también el método <span style="font-family: courier new,courier;"><strong>hashCode</strong></span>. En el API de java para <span style="font-family: andale mono,times;">Object</span> del método <strong><span style="font-family: courier new,courier;">hashCode</span></strong> se especifica lo siguiente:</p>
<ul style="text-align: justify;">
<li>Cuando este método es invocado sobre el mismo objeto una o más veces durante una ejecución en una aplicación, el <span style="font-family: courier new,courier;"><strong>hashCode</strong></span> debe de ser consistente devolviendo siempre el mismo valor, siempre que no se modifique el objeto. Este valor no tiene que ser consistente entre ejecuciones distintas de la aplicación.</li>
<li>Si dos objetos son iguales segun el método <span style="font-family: courier new,courier;"><strong>equals</strong></span>, entonces el <span style="font-family: courier new,courier;"><strong>hashCode</strong></span> de los dos objetos tiene que ser el mismo.</li>
<li style="text-align: justify;">Si dos objetos no son iguales, el <span style="font-family: courier new,courier;"><strong>hashCode</strong></span> no tiene que ser necesariamente distinto, pero es recomendable que lo sea.</li>
</ul>
<p>Unos pasos para implementar un buen método <span style="font-family: courier new,courier;"><strong>hashCode</strong></span> son:</p>
<ul>
<li>Declaramos una variable entera y le asignamos un número, por ejemplo <span style="font-family: courier new,courier;">result=17</span>.</li>
<li>Para cada campo significativo de nuestro objeto, <span style="font-family: courier new,courier;">f:</span>
<ul>
<li>Calculamos en <span style="font-family: courier new,courier;">int c </span>el valor de:
<ul>
<li>Tipo <span style="font-family: courier new,courier;">boolean</span>: hacemos <span style="font-family: courier new,courier;">(f?1 : 0)</span></li>
<li>Tipos <span style="font-family: courier new,courier;">byte, char, short, o int</span>: hacemos <span style="font-family: courier new,courier;">(int) f</span></li>
<li>Tipo <span style="font-family: andale mono,times;">Long</span>: hacemos <span style="font-family: courier new,courier;">(int)(f^(f&gt;&gt;&gt;32))</span></li>
<li>Tipo <span style="font-family: courier new,courier;">Float</span>: hacemos <span style="font-family: courier new,courier;">Float.doubleToIntBits(f)</span></li>
<li>Tipo <span style="font-family: courier new,courier;">Double</span>: hacemos <span style="font-family: courier new,courier;">Double.doubleToLongBits(f) </span>y  <span style="font-family: courier new,courier;">(int)(f^(f&gt;&gt;&gt;32))</span></li>
<li>Si es una referencia a un objeto, llamamos al <strong><span style="font-family: courier new,courier;">hashCode</span></strong> del objeto. Si la referencia es nula, devolvemos un 0.</li>
<li>Si es un <span style="font-family: courier new,courier;">Array</span>, utilizamos el método <span style="font-family: courier new,courier;">Arrays.hashCode.</span></li>
</ul>
</li>
<li>Acumulamos el valor de <span style="font-family: courier new,courier;">c</span> en <span style="font-family: courier new,courier;">result</span> : <span style="font-family: courier new,courier;">result = 31 * result + c</span></li>
</ul>
</li>
<li>Devolvemos el valor de <span style="font-family: courier new,courier;">result</span></li>
</ul>
<p>Podemos excluir los campos que no comprobemos en el método <span style="font-family: courier new,courier;"><strong>equals</strong></span>, pero no es recomendable.</p>
<pre class="brush: java; title: ; notranslate">
//Ejemplo de cómo sobreescribir el método hashCode
@Override
public int hashCode() {
  int result = 17;
  result = 31 * result + num;
  result = 31 * result + (direccion != null ?
           direccion.hashCode() : 0);
  result = 31 * result + (int) (Double.doubleToLongBits(precio)
           ^((Double.doubleToLongBits(precio) &gt;&gt;&gt; 32));
  result = 31 * result + (propietarios != null) ?
           propietarios.hashCode() : 0);
 return result;
 }
</pre>
<p>Fuente: Libro Effective Java de Joshua Bloch</p>
]]></content:encoded>
			<wfw:commentRss>http://anabuigues.com/2010/07/06/como-sobreescribir-los-metodos-equals-y-hashcode-de-java/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Definir una Singleton en Java mediante un enum</title>
		<link>http://anabuigues.com/2010/02/15/definir-una-singleton-en-java-mediante-un-enum/</link>
		<comments>http://anabuigues.com/2010/02/15/definir-una-singleton-en-java-mediante-un-enum/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 19:10:47 +0000</pubDate>
		<dc:creator>Ana Buigues</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Enum]]></category>
		<category><![CDATA[Patrones Java]]></category>
		<category><![CDATA[Singleton]]></category>
		<guid isPermaLink="false">http://anabuigues.com/?p=348</guid>
		<description><![CDATA[El otro día leyendo el libro de Effective Java de Joshua Bloch, me encontré con una nueva forma de declarar el patrón de diseño Singleton. Una singleton es simplemente una clase que es instanciada exactamente una vez. Antes de Java 1.5 había dos formas de implementar una singleton, ambas se basan en un contructor privado [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">El otro día leyendo el libro de <a href="http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683" rel="nofollow" target="_blank">Effective Java</a> de Joshua Bloch, me encontré con una nueva forma de declarar el patrón de diseño <a href="http://es.wikipedia.org/wiki/Singleton" rel="nofollow" target="_blank">Singleton</a>.</p>
<p style="text-align: justify;">Una <strong>singleton</strong> es simplemente una clase que es instanciada exactamente una vez. Antes de <strong>Java</strong> 1.5 había dos formas de implementar una <strong>singleton</strong>, ambas se basan en un contructor privado y en proporcionar un miembro público y estático que da acceso a una sola instancia. A partir de <strong>Java</strong> 1.5 aparece una tercera opción para implementar una <strong>singleton</strong>, simplemente mediante un tipo enumerado con un único elemento:</p>
<pre class="brush: java; title: ; notranslate">
public enum Singleton {
    INSTANCE;
    public String nombre(){
           return this.getClass().getName();
    }
}
</pre>
<p style="text-align: justify;"><span id="more-348"></span>Este enfoque es funcionamente equivalente a los dos anteriores, excepto porque es más conciso y ofrece una rigurosa garantía contra múltiples instanciaciones, ya que con los métodos anteriores podíamos invocar al constructor privado mediante reflexión y obtener más de una instancia. En el siguiente ejemplo, creamos por reflexión dos enums:</p>
<pre class="brush: java; title: ; notranslate">
public static void main(String[] args) {
  Constructor&lt;Singleton&gt; ctor = Singleton.class.getDeclaredConstructor(String.class, int.class);
  Method acqMethod = ctor.getClass().getDeclaredMethod(&quot;acquireConstructorAccessor&quot;);
  acqMethod.setAccessible(true);
  acqMethod.invoke(ctor);
  Field accessorField = ctor.getClass().getDeclaredField(&quot;constructorAccessor&quot;);
  accessorField.setAccessible(true);
  Object accessor = accessorField.get(ctor);
  Method newInstanceMethod = accessor.getClass().getMethod(&quot;newInstance&quot;, Object[].class);
  newInstanceMethod.setAccessible(true);
  Singleton singleton1 = (Singleton) newInstanceMethod.invoke(accessor, new Object[]{new Object[]{&quot;hey&quot;, 1}});
  Singleton singleton2 = (Singleton) newInstanceMethod.invoke(accessor, new Object[]{new Object[]{&quot;hey&quot;, 1}});
  if(singleton1 == singleton2){
  	System.out.println(&quot;son iguales los objetos&quot;);
  }else{
  	System.out.println(&quot;no son iguales los objetos&quot;);
  }
  if(singleton1.INSTANCE == singleton2.INSTANCE){
	System.out.println(&quot;son iguales las instancias&quot;);
  }else{
	System.out.println(&quot;no son iguales las instancias&quot;);
  }
}
</pre>
<p style="text-align: justify;">Como resultado de ejecutar el código, obtenemos dos objetos distintos, pero las instancias de su interior son la misma y por tanto mediante reflexión no hemos roto la singleton.</p>
<p style="text-align: justify;">Además dado que los enumerados implementan la interfaz serializable no necesitamos hacer nada adicional para serializar este objeto.</p>
<p style="text-align: justify;">Según Joshua Bloch es la mejor manera de instanciar una <strong>singleton.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://anabuigues.com/2010/02/15/definir-una-singleton-en-java-mediante-un-enum/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

