Implementando a Interface Comparable
O método equals() nos permite verificar se dois objetos são iguais, mas não nos ajuda a estabelecer uma ordenação. Para isso, Java fornece a interface Comparable, que nos permite definir uma "ordenação natural" para nossos objetos.
Entendendo a Interface Comparable
A interface Comparable<T> possui um único método, compareTo(T o), que compara o objeto atual com outro objeto do mesmo tipo. O método retorna:
- Um inteiro negativo se o objeto atual for menor que o outro objeto
- Zero se o objeto atual for igual ao outro objeto
- Um inteiro positivo se o objeto atual for maior que o outro objeto
Ao implementar essa interface, podemos definir como os objetos de nossa classe devem ser ordenados.
Atualizando a Classe Student
Vamos atualizar nossa classe Student para implementar a interface Comparable. Definiremos a ordenação natural com base na nota do aluno (notas mais altas vêm primeiro), depois pela idade (alunos mais jovens vêm primeiro) e, finalmente, pelo nome (ordem alfabética).
Atualize seu arquivo Student.java:
public class Student implements Comparable<Student> {
private String name;
private int age;
private double grade;
// Existing constructor, getters, toString, equals, and hashCode methods...
// Implement compareTo method from Comparable interface
@Override
public int compareTo(Student other) {
// Compare by grade (descending order)
if (Double.compare(other.grade, this.grade) != 0) {
return Double.compare(other.grade, this.grade);
}
// If grades are equal, compare by age (ascending order)
if (this.age != other.age) {
return Integer.compare(this.age, other.age);
}
// If grades and ages are equal, compare by name (alphabetical order)
return this.name.compareTo(other.name);
}
}
Criando um Teste para a Implementação Comparable
Vamos criar um novo arquivo ComparableTest.java para testar nossa implementação Comparable:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ComparableTest {
public static void main(String[] args) {
// Create a list of students
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 20, 85.5));
students.add(new Student("Bob", 22, 90.0));
students.add(new Student("Charlie", 19, 78.3));
students.add(new Student("David", 21, 85.5));
students.add(new Student("Eve", 20, 92.7));
// Display unsorted list
System.out.println("Unsorted list of students:");
for (Student student : students) {
System.out.println(student);
}
// Sort the list using the natural ordering defined by Comparable
Collections.sort(students);
// Display sorted list
System.out.println("\nSorted list of students (by grade descending, then age ascending, then name):");
for (Student student : students) {
System.out.println(student);
}
// Let's compare some students directly using compareTo
Student alice = students.get(3); // Alice should be at index 3 after sorting
Student bob = students.get(1); // Bob should be at index 1 after sorting
System.out.println("\nComparing students directly using compareTo:");
int comparison = alice.compareTo(bob);
System.out.println("alice.compareTo(bob) = " + comparison);
if (comparison < 0) {
System.out.println("Alice comes before Bob in the natural ordering");
} else if (comparison > 0) {
System.out.println("Bob comes before Alice in the natural ordering");
} else {
System.out.println("Alice and Bob are equal in the natural ordering");
}
}
}
Compilar e Executar
Vamos compilar e executar nosso código:
javac Student.java ComparableTest.java
java ComparableTest
A saída deve ser semelhante a:
Unsorted list of students:
Student{name='Alice', age=20, grade=85.5}
Student{name='Bob', age=22, grade=90.0}
Student{name='Charlie', age=19, grade=78.3}
Student{name='David', age=21, grade=85.5}
Student{name='Eve', age=20, grade=92.7}
Sorted list of students (by grade descending, then age ascending, then name):
Student{name='Eve', age=20, grade=92.7}
Student{name='Bob', age=22, grade=90.0}
Student{name='Alice', age=20, grade=85.5}
Student{name='David', age=21, grade=85.5}
Student{name='Charlie', age=19, grade=78.3}
Comparing students directly using compareTo:
alice.compareTo(bob) = 1
Bob comes before Alice in the natural ordering
Observe que os alunos agora estão classificados por sua nota em ordem decrescente. Quando as notas são iguais (como com Alice e David, ambos com 85,5), eles são classificados por idade em ordem crescente.
A interface Comparable fornece uma ordenação natural para nossos objetos, mas e se quisermos classificar objetos de maneiras diferentes em momentos diferentes? Por exemplo, às vezes podemos querer classificar os alunos por nome e, outras vezes, por idade. É aí que a interface Comparator entra em ação, que exploraremos na próxima etapa.