compareTo() y Comparable
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 44 de 87.
La interfaz Comparable permite que los objetos definan su orden natural. Al implementar esta interfaz, su clase puede ser ordenada automáticamente usando métodos como Collections.sort() o almacenada en colecciones ordenadas como TreeSet.
La interfaz requiere que implementes un único método: compareTo(). Este método compara el objeto actual con otro objeto y devuelve un entero que indica su orden relativo:
- Valor negativo: este objeto va antes que el otro
- Cero: ambos objetos son iguales
- Valor positivo: este objeto va después del otro
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person other) {
return this.age - other.age; // Ordenar por edad de forma ascendente
}
}Una vez implementado, la ordenación se vuelve sencilla:
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people); // Ahora ordenado por edad: Bob, AlicePara comparar cadenas u otros campos Comparable, puedes delegar en su método compareTo() en lugar de usar la resta: return this.name.compareTo(other.name);. Este enfoque es más seguro y maneja los casos de borde adecuadamente.
Desafío
FácilVamos a construir un sistema de clasificación de películas que utiliza la interfaz Comparable para ordenar películas por sus calificaciones. Crearás una clase Movie que sepa cómo compararse con otras películas, permitiendo el ordenamiento automático de mayor a menor calificación.
Organizarás tu código en dos archivos:
Movie.java: Crea una clase que represente una película que pueda compararse con otras películas. Una Movie tiene tres campos privados:title(String),director(String) yrating(double, de 0.0 a 10.0). Incluye un constructor para inicializar todos los campos y métodos getter para cada uno.Haz que tu clase Movie implemente
Comparable<Movie>y sobrescriba el métodocompareTo(). Las películas deben ordenarse por calificación en orden descendente (la calificación más alta primero). Al comparar doubles, usaDouble.compare()para una comparación segura; ¡recuerda invertir el orden para el ordenamiento descendente!Sobrescribe
toString()para devolver:[title] by [director] - Rating: [rating]Main.java: Da vida a tu clase Movie creando una lista de películas y ordenándolas. Recibirás la entrada de tres películas, cada una en una línea separada con el formato:title,director,ratingAnaliza cada línea para crear objetos Movie, añádelos a un
ArrayList, luego usaCollections.sort()para ordenar la lista. ¡Gracias a tu implementación deComparable, las películas se organizarán automáticamente por calificación!Después de ordenar, imprime cada película en su propia línea usando el formato
toString(). La película con la calificación más alta debe aparecer primero.
Recibirás tres líneas de entrada, cada una con datos de películas en el formato: title,director,rating
Por ejemplo, una línea de entrada podría verse así: Inception,Christopher Nolan,8.8
Recuerda importar java.util.ArrayList, java.util.Collections y java.util.Scanner en tu archivo Main. ¡Observa cómo implementar Comparable te permite ordenar tus objetos personalizados con una sola llamada al método, sin necesidad de un comparador adicional!
Hoja de referencia
La interfaz Comparable permite que los objetos definan su orden natural para la clasificación automática.
Implemente el método compareTo() que devuelve:
- Valor negativo: este objeto va antes que el otro
- Cero: ambos objetos son iguales
- Valor positivo: este objeto va después del otro
public class Person implements Comparable<Person> {
private int age;
@Override
public int compareTo(Person other) {
return this.age - other.age; // Ordenar por edad de forma ascendente
}
}Clasifique objetos usando Collections.sort():
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people); // Clasificado por edadPara comparar cadenas, delegue en su método compareTo():
return this.name.compareTo(other.name);Para comparar doubles de forma segura, use Double.compare():
return Double.compare(this.rating, other.rating); // Ascendente
return Double.compare(other.rating, this.rating); // DescendentePruébalo tú mismo
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leer tres líneas de datos de películas
String line1 = scanner.nextLine();
String line2 = scanner.nextLine();
String line3 = scanner.nextLine();
// TODO: Crear un ArrayList para almacenar objetos Movie
// TODO: Analizar cada línea (formato: título,director,calificación)
// Sugerencia: Usar split(",") para separar las partes
// Sugerencia: Usar Double.parseDouble() para la calificación
// TODO: Crear objetos Movie y añadirlos a la lista
// TODO: Ordenar la lista usando Collections.sort()
// TODO: Imprimir cada película (una por línea)
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Iterator