tutorial interfaz interfaces gui graficas grafica español ejemplos definicion java

interfaz - ¿Por qué una implementación de Java debería ser comparable?



jlabel definicion (10)

Aquí hay una muestra de la vida real. Tenga en cuenta que String también implementa Comparable .

class Author implements Comparable<Author>{ String firstName; String lastName; @Override public int compareTo(Author other){ // compareTo should return < 0 if this is supposed to be // less than other, > 0 if this is supposed to be greater than // other and 0 if they are supposed to be equal int last = this.lastName.compareTo(other.lastName); return last == 0 ? this.firstName.compareTo(other.firstName) : last; } }

luego..

/** * List the authors. Sort them by name so it will look good. */ public List<Author> listAuthors(){ List<Author> authors = readAuthorsFromFileOrSomething(); Collections.sort(authors); return authors; } /** * List unique authors. Sort them by name so it will look good. */ public SortedSet<Author> listUniqueAuthors(){ List<Author> authors = readAuthorsFromFileOrSomething(); return new TreeSet<Author>(authors); }

¿Por qué se usa Java Comparable ? ¿Por qué alguien implementaría Comparable en una clase? ¿Cuál es un ejemplo de la vida real en el que necesita implementar un sistema comparable?


Bien, pero ¿por qué no simplemente definir un compareTo() sin implementar una interfaz comparable? Por ejemplo, una clase de City definida por su name y temperature y

public int compareTo(City theOther) { if (this.temperature < theOther.temperature) return -1; else if (this.temperature > theOther.temperature) return 1; else return 0; }


Citado del javadoc;

Esta interfaz impone un orden total en los objetos de cada clase que lo implementa. Este orden se conoce como el orden natural de la clase, y el método compareTo de la clase se conoce como su método de comparación natural.

Las listas (y las matrices) de los objetos que implementan esta interfaz se pueden ordenar automáticamente por Collections.sort (y Arrays.sort). Los objetos que implementan esta interfaz se pueden usar como claves en un mapa ordenado o como elementos en un conjunto ordenado, sin la necesidad de especificar un comparador.

Editar: ... e hizo que el importante sea negrita.


Comparable define un orden natural. Lo que esto significa es que lo está definiendo cuando un objeto se debe considerar "menor que" o "mayor que".

Supongamos que tiene un montón de enteros y desea ordenarlos. Eso es bastante fácil, solo ponlos en una colección ordenada, ¿verdad?

TreeSet<Integer> m = new TreeSet<Integer>(); m.add(1); m.add(3); m.add(2); for (Integer i : m) ... // values will be sorted

Pero ahora supongamos que tengo un objeto personalizado, donde la clasificación tiene sentido para mí, pero no está definido. Digamos que tengo datos que representan distritos por código postal con densidad de población, y quiero ordenarlos por densidad:

public class District { String zipcode; Double populationDensity; }

Ahora la forma más fácil de ordenarlos es definirlos con un orden natural mediante la implementación de Comparable, lo que significa que hay una forma estándar en que estos objetos se definen para ser ordenados .:

public class District implements Comparable<District>{ String zipcode; Double populationDensity; public int compareTo(District other) { return populationDensity.compareTo(other.populationDensity); } }

Tenga en cuenta que puede hacer lo equivalente definiendo un comparador. La diferencia es que el comparador define la lógica de pedido fuera del objeto . Quizás en un proceso separado necesite pedir los mismos objetos por código postal, en ese caso el orden no es necesariamente una propiedad del objeto, o difiere del orden natural de los objetos. Puede usar un comparador externo para definir un orden personalizado en enteros, por ejemplo clasificándolos por su valor alfabético.

Básicamente, la lógica de ordenamiento debe existir en alguna parte. Eso puede ser -

  • en el objeto en sí, si es naturalmente comparable (se extiende con números enteros equivalentes)

  • suministrado en un comparador externo, como en el ejemplo anterior.


Comparable se usa para comparar instancias de tu clase. Podemos comparar instancias de muchas maneras, es por eso que necesitamos implementar un método compareTo para saber cómo (atributos) queremos comparar instancias.

Clase de Dog :

package test; import java.util.Arrays; public class Main { public static void main(String[] args) { Dog d1 = new Dog("brutus"); Dog d2 = new Dog("medor"); Dog d3 = new Dog("ara"); Dog[] dogs = new Dog[3]; dogs[0] = d1; dogs[1] = d2; dogs[2] = d3; for (int i = 0; i < 3; i++) { System.out.println(dogs[i].getName()); } /** * Output: * brutus * medor * ara */ Arrays.sort(dogs, Dog.NameComparator); for (int i = 0; i < 3; i++) { System.out.println(dogs[i].getName()); } /** * Output: * ara * medor * brutus */ } }

Clase Main :

package test; import java.util.Arrays; public class Main { public static void main(String[] args) { Dog d1 = new Dog("brutus"); Dog d2 = new Dog("medor"); Dog d3 = new Dog("ara"); Dog[] dogs = new Dog[3]; dogs[0] = d1; dogs[1] = d2; dogs[2] = d3; for (int i = 0; i < 3; i++) { System.out.println(dogs[i].getName()); } /** * Output: * brutus * medor * ara */ Arrays.sort(dogs, Dog.NameComparator); for (int i = 0; i < 3; i++) { System.out.println(dogs[i].getName()); } /** * Output: * ara * medor * brutus */ } }

Aquí hay un buen ejemplo de cómo usar comparable en Java:

http://www.onjava.com/pub/a/onjava/2003/03/12/java_comp.html?page=2


Cuando implemente una interfaz Comparable , debe implementar el método compareTo() . Lo necesita para comparar objetos, para usar, por ejemplo, el método de clasificación de la clase ArrayList . Necesita una forma de comparar sus objetos para poder ordenarlos. Por lo tanto, necesita un compareTo() personalizado compareTo() en su clase para que pueda usarlo con el método de ordenación ArrayList . El compareTo() devuelve -1,0,1.

Acabo de leer un capítulo correspondiente en Java Head 2.0, todavía estoy aprendiendo.


El hecho de que una clase implemente Comparable significa que puedes tomar dos objetos de esa clase y compararlos. Algunas clases, como ciertas colecciones (función de clasificación en una colección) que mantienen los objetos en orden, dependen de que sean comparables (para ordenar, necesita saber qué objeto es el "más grande", etc.).


La mayoría de los ejemplos anteriores muestran cómo reutilizar un objeto comparable existente en la función compareTo. Si desea implementar su propia comparación, cuando desee comparar dos objetos de la misma clase, diga un objeto AirlineTicket que desee ordenar por precio (menos se clasifica primero), seguido de número de escala (nuevamente, menos es el primero), harías lo siguiente:

class AirlineTicket implements Comparable<Cost> { public double cost; public int stopovers; public AirlineTicket(double cost, int stopovers) { this.cost = cost; this.stopovers = stopovers ; } public int compareTo(Cost o) { if(this.cost != o.cost) return Double.compare(this.cost, o.cost); //sorting in ascending order. if(this.stopovers != o.stopovers) return this.stopovers - o.stopovers; //again, ascending but swap the two if you want descending return 0; } }


Por ejemplo, cuando quiere tener una colección ordenada o un map


Una manera fácil de implementar múltiples comparaciones de campo es con Guava''s ComparisonChain - entonces puedes decir

public int compareTo(Foo that) { return ComparisonChain.start() .compare(lastName, that.lastName) .compare(firstName, that.firstName) .compare(zipCode, that.zipCode) .result(); }

en lugar de

public int compareTo(Person other) { int cmp = lastName.compareTo(other.lastName); if (cmp != 0) { return cmp; } cmp = firstName.compareTo(other.firstName); if (cmp != 0) { return cmp; } return Integer.compare(zipCode, other.zipCode); } }