Java Comparable Interface

Java permite comparar valores primitivos usando os operadores <, <=, >, >=, ==, !=.

Mas para comparar objetos esses operadores não são suportados e uma abordagem diferente deve ser utilizada.

Como comparar dois objetos do tipo Task em um sistema de gerenciamento de tarefas simples. Java permite a comparação de objetos utilizando a interface Comparable. Após definir como comparar os objetos é bem simples ordenar a list de tasks utilizando a função sort das classes Collections ou Arrays.

Collections.sort(tasks);
Arrays.sort(tasks);

Por padrão uma classe não implementa a interface Comparable. Para tornar a classe comparável é necessário implementar a interface Comparable e sobre-escrever o método compareTo().

O método compareTo() define como os objetos serão comparados entre eles. Veja a definição da interface Comparable.

public interface Comparable {
    public int compareTo(T o);
}

O método compareTo() retorna um valor inteiro que define se o objeto e menor que, igual ou maior que o outro objeto.

  • Negativo – Indica o objeto é menor que o outro.
  • Zero – Indica que o objeto é igual ao outro.
  • Positivo – Indica que o objeto é maior que o outro.

Java possui muitas classes que implementam a interface Comparable tais como String, Integer, Date, Calendar e muitas outras. Assim garantindo a ordem dos objetos.

Exemplo

O exemplo mostra como implementar a interface Comparable para uma determinada classe e como definir o método compareTo() para comparar dois objetos diferentes.

No exemplo o atributo priority será comparado utilizando o método compareTo() definido na classe Integer.


import java.util.Date;
import java.util.Objects;
import java.util.UUID;

public class Task implements Comparable {

    private String id;
    private String name;
    private String description;
    private Integer priority;
    private Date created;
    private Status status;

    public Task() {
    }

    public Task(String name, Integer priority) {
        this.id = UUID.randomUUID().toString();
        this.name = name;
        this.priority = priority;
        this.created = new Date();
    }
    
    // The Getters and Setters were omitted

    public int compareTo(Task anotherTask) {
        return this.priority.compareTo(anotherTask.priority);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Task task = (Task) o;
        return id.equals(task.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "{name=" + name + ", priority=" + priority +"}";

    }
}

O método compareTo() podería ter sido implementado como o mostrado abaixo.

@Override
public int compareTo(Task anotherTask) {
   if(this.priority < anotherTask.getPriority()) {
       return -1;
   }
   if(this.priority > anotherTask.getPriority()) {
       return 1;
   }
   return 0;
}

O código abaixo mostra como ordenar uma lista de Tasks baseado na definição do método compareTo() da classes Task.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparableTest {

    public static void main(String[] args) {

        List listOfTasks = new ArrayList<>();
        listOfTasks.add(new Task("Task 1", 1));
        listOfTasks.add(new Task("Task 2", 3));
        listOfTasks.add(new Task("Task 3", 2));
        listOfTasks.add(new Task("Task 4", 5));


        System.out.println("Before Sort");
        System.out.println(listOfTasks);

        Collections.sort(listOfTasks);

        System.out.println("After Sort");
        System.out.println(listOfTasks);
    }
}
# output:

Before Sort
[{name=Task 1, priority=1}, {name=Task 2, priority=3}, {name=Task 3, priority=2}, {name=Task 4, priority=5}]

After Sort
[{name=Task 1, priority=1}, {name=Task 3, priority=2}, {name=Task 2, priority=3}, {name=Task