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, tu clase se puede ordenar automáticamente mediante métodos como Collections.sort() o almacenarse 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 que el 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 Integer.compare(this.age, other.age); // Ordenar por edad ascendente
}
}Una vez implementada, 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 correctamente los casos límite. Para los campos int, es preferible usar Integer.compare(a, b) en lugar de a - b, porque la resta puede provocar un desbordamiento con valores extremos.
Desafío
FácilConstruyamos un sistema de clasificación de películas que use la interfaz Comparable para ordenar las películas según sus puntuaciones. Crearás una clase Movie que sepa cómo compararse con otras películas, lo que permitirá ordenarlas automáticamente de la puntuación más alta a la más baja.
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 puntuación en orden descendente (la puntuación más alta primero). Al comparar valores double, usaDouble.compare()para realizar una comparación segura: ¡recuerda invertir el orden para la clasificación descendente!Sobrescribe
toString()para que devuelva:[title] by [director] - Rating: [rating]Main.java: Dale vida a tu clase Movie creando una lista de películas y ordenándolas. Recibirás los datos 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
ArrayListy, después, usaCollections.sort()para ordenar la lista. Gracias a tu implementación deComparable, ¡las películas se organizarán automáticamente por puntuación!Después de ordenarlas, imprime cada película en su propia línea usando el formato de
toString(). La película con la puntuación más alta debe aparecer primero.
Recibirás tres líneas de entrada, cada una con los datos de una película 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 a un método: ¡no necesitas un comparador adicional!
Prué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);
// Lee tres líneas de datos de películas
String line1 = scanner.nextLine();
String line2 = scanner.nextLine();
String line3 = scanner.nextLine();
// TODO: Crea un ArrayList para almacenar objetos Movie
// TODO: Analiza cada línea (formato: title,director,rating)
// Hint: Usa split(",") para separar las partes
// Hint: Usa Double.parseDouble() para el rating
// TODO: Crea objetos Movie y añádelos a la lista
// TODO: Ordena la lista usando Collections.sort()
// TODO: Imprime 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 IteratorPractica por tu cuenta: Compilador de Java online