miércoles, 23 de noviembre de 2011

Interfaz Comparator. Comparadores en Java

Cuando trabajamos con las colecciones en Java a veces necesitamos ordenar primero los elementos para luego realizar una determinada acción. 

Si trabajamos con objetos o tipos simples como números (java.lang.Number, int) o cadenas (java.lang.String) la ordenación es más fácil. Para ordenar un array de este tipo lo único que tenemos que hacer es utilizar la sentencia siguiente y ya tendríamos nuestro array ordenado:


java.util.Arrays.sort(arrayDeNumeros); 

Pero imaginemos ahora que tenemos que realizar una determinada acción sobre un tipo complejo (Persona, Departamento...). Si queremos ordenar un array de objetos complejos debemos decir primero qué criterios de ordenación se deben seguir. ¿Cómo se hace esto? Pues con la interfaz java.util.Comparator.

Hay dos opciones: implementar la interfaz Comparator en la propia clase del objeto que queremos ordenar o bien hacerlo en una clase diferente. La opción más elegante es la segunda, tener clases diferentes que implementen la interfaz Comparator por cada método de ordenación que queremos definir.

Por ejemplo, imaginemos que tenemos una clase llamada Numero que representa los números posibles de un sorteo de lotería. A veces queremos ordenar la lista de números del sorteo por el valor del propio número y otras veces queremos ordenar la lista por la probabilidad con la que hayamos calculado que puede aparecer el número en un sorteo.

El código de la clase Numero es el siguiente:


public class Numero {

 private int numero;

 private int valor;

 private float probabilidad;

 private int numeroSorteos;

 private int tipoItem;

 private float peso;

 private String anillo;

 /**
  * @param numero
  * @param valor
  * @param probabilidad
  * @param numeroSorteos
  * @param tipoItem
  * @param peso
  * @param anillo
  */
 public Numero(int numero, int valor, float probabilidad, int numeroSorteos,
   int tipoItem, int peso, String anillo) {
  this.numero = numero;
  this.valor = valor;
  this.probabilidad = probabilidad;
  this.numeroSorteos = numeroSorteos;
  this.tipoItem = tipoItem;
  this.peso = peso;
  this.anillo = anillo;
 }

 public Numero() {

 }

 public int getNumero() {
  return numero;
 }

 public void setNumero(int numero) {
  this.numero = numero;
 }

 public int getValor() {
  return valor;
 }

 public void setValor(int valor) {
  this.valor = valor;
 }

 public float getProbabilidad() {
  return probabilidad;
 }

 public void setProbabilidad(float probabilidad) {
  this.probabilidad = probabilidad;
 }

 public int getNumeroSorteos() {
  return numeroSorteos;
 }

 public void setNumeroSorteos(int numeroSorteos) {
  this.numeroSorteos = numeroSorteos;
 }

 public int getTipoItem() {
  return tipoItem;
 }

 public void setTipoItem(int tipoItem) {
  this.tipoItem = tipoItem;
 }

 public float getPeso() {
  return peso;
 }

 public void setPeso(float peso) {
  this.peso = peso;
 }

 public String getAnillo() {
  return anillo;
 }

 public void setAnillo(String anillo) {
  this.anillo = anillo;
 }

 @Override
 public boolean equals(Object obj) {
  if (obj == null)
   return false;

  if (!(obj instanceof Numero)) {
   return false;
  }

  Numero item = (Numero) obj;
  if (this.numero == item.numero) {
   return true;
  }
  return false;

 }

 @Override
 public int hashCode() {
  // TODO Auto-generated method stub
  return this.numero;
 }

}


Para crear el comparador que ordena los números por su valor nos creamos una clase que implemente Comparator y sobrescriba el método compare(Object,Object). Este método devuelve un número negativo, cero o un número positivo si el primer argumento es menor, igual o mayor que el segundo argumento. Para ordenar tendremos en cuenta al atributo valor.

El código lo tenéis aquí:


class ItemComparator implements Comparator {

 public void ItemComparator() {
 }

 public int compare(Object arg0, Object arg1) {
  Integer item1 = ((Numero) arg0).getValor();
  Integer item2 = ((Numero) arg1).getValor();  
  return item1.compareTo(item2);
 }

}


Para crear el comparador que nos ordenará la lista de números por probabilidad haremos lo mismo pero esta vez lo que haremos será sobrescribir el método compare(Object,Object) ordenando por el atributo probabilidad.


El código lo tenéis aquí:


class ProbabilidadComparator implements Comparator {
 public ProbabilidadComparator() {

 }

 public int compare(Object arg0, Object arg1) {  
  Float item1 = ((Numero) arg0).getProbabilidad();
  Float item2 = ((Numero) arg1).getProbabilidad();  
  return item1.compareTo(item2);
 }

}

Por último, para hacer la ordenación de nuestro array le pasaremos al método sort de la clase java.util.Arrays la implementación de la clase Comparator que queramos, dependiendo del criterio de ordenación que queramos utilizar. 

En el siguiente código ordenamos el array por probabilidad:




...
Arrays.sort(n, new ProbabilidadComparator());
...


Como siempre, espero haberos ayudado con vuestros programas en Java.


Salu2.

1 comentario:

  1. Este comentario ha sido eliminado por un administrador del blog.

    ResponderEliminar