0Pricing
Java Academy · Aula

A Interface Comparable

Implemente Comparable para dar a uma classe uma ordenação natural e use-a com Collections.sort.

A Interface Comparable é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

A interface Comparable

Comparable<T> fornece uma ordem natural para uma classe. Implemente-a para tornar as instâncias ordenáveis com Collections.sort(), Arrays.sort() e coleções ordenadas, como TreeSet.

Implementando Comparable

Implemente compareTo(T other) retornando um valor negativo (este objeto < other), zero (iguais) ou um valor positivo (este objeto > other).

class Product implements Comparable<Product> {
    private final String name;
    private final double price;

    Product(String name, double price) {
        this.name = name; this.price = price;
    }

    @Override
    public int compareTo(Product other) {
        return Double.compare(this.price, other.price); // ascending by price
    }

    @Override public String toString() { return name + "($" + price + ")"; }
}

List<Product> products = new ArrayList<>(List.of(
    new Product("Mouse", 29.99),
    new Product("Laptop", 999.0),
    new Product("Keyboard", 79.99)
));
Collections.sort(products);
System.out.println(products); // [Mouse($29.99), Keyboard($79.99), Laptop($999.0)]

O contrato de compareTo

Implementar Comparable corretamente exige satisfazer um contrato:

  • Antissimetria: sgn(a.compareTo(b)) == -sgn(b.compareTo(a))
  • Transitividade: se a > b e b > c, então a > c
  • Consistência: a.compareTo(b) == 0 implica a.equals(b); essa consistência é fortemente recomendada

Comparando tipos primitivos com segurança

Nunca subtraia tipos primitivos em compareTo: o estouro de inteiros pode produzir resultados incorretos. Use Integer.compare(), Double.compare() e outros métodos semelhantes.

// WRONG: integer subtraction can overflow
int compareTo(Player other) {
    return this.score - other.score; // overflow if scores differ by > Integer.MAX_VALUE
}

// CORRECT: use Integer.compare
int compareTo(Player other) {
    return Integer.compare(this.score, other.score);
}

// For strings: delegate to String.compareTo
int compareTo(Player other) {
    return this.name.compareTo(other.name); // String handles it correctly
}

Ordenação natural em TreeSet

As classes que implementam Comparable são inseridas automaticamente na posição correta em coleções ordenadas, como TreeSet e TreeMap.

class Priority implements Comparable<Priority> {
    enum Level { LOW, MEDIUM, HIGH, CRITICAL }
    final Level level;
    final String task;
    Priority(Level level, String task) { this.level = level; this.task = task; }
    @Override
    public int compareTo(Priority other) {
        return this.level.compareTo(other.level); // enum ordinal order
    }
    @Override public String toString() { return level + ": " + task; }
}

TreeSet<Priority> queue = new TreeSet<>();
queue.add(new Priority(Priority.Level.CRITICAL, "Fix prod crash"));
queue.add(new Priority(Priority.Level.LOW, "Update docs"));
queue.add(new Priority(Priority.Level.HIGH, "Deploy feature"));
queue.forEach(System.out::println);
// LOW: Update docs
// HIGH: Deploy feature
// CRITICAL: Fix prod crash

Comparable com vários campos

Para ordenar por vários campos, encadeie as comparações: primeiro o campo principal e, se houver empate, o campo secundário.

class Employee implements Comparable<Employee> {
    final String dept, name;
    final double salary;

    Employee(String dept, String name, double salary) {
        this.dept = dept; this.name = name; this.salary = salary;
    }

    @Override
    public int compareTo(Employee other) {
        int deptCmp = this.dept.compareTo(other.dept);
        if (deptCmp != 0) return deptCmp;           // primary: by dept
        return this.name.compareTo(other.name);      // secondary: by name
    }
}

Consistência entre Comparable e equals

É fortemente recomendado, embora não seja obrigatório, que a.compareTo(b) == 0 se, e somente se, a.equals(b). Violar isso causa erros sutis em conjuntos e mapas ordenados.

// BigDecimal violates this: new BigDecimal("2.0").compareTo(new BigDecimal("2.00")) == 0
// but new BigDecimal("2.0").equals(new BigDecimal("2.00")) == false

// This causes TreeSet to treat them as equal (only one stored)
TreeSet<java.math.BigDecimal> set = new TreeSet<>();
set.add(new java.math.BigDecimal("2.0"));
set.add(new java.math.BigDecimal("2.00"));
System.out.println(set.size()); // 1 — compareTo-equal → same element

Ordenando com Collections.sort

Collections.sort() e Arrays.sort() usam a ordem natural definida por Comparable.

List<String> names = new ArrayList<>(List.of("Charlie", "Alice", "Bob"));
Collections.sort(names); // natural alphabetical order
System.out.println(names); // [Alice, Bob, Charlie]

String[] arr = {"banana", "apple", "cherry"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); // [apple, banana, cherry]

// Stream sorted() uses natural order
names.stream().sorted().forEach(System.out::println);

Comparable na busca binária

Collections.binarySearch() exige que a lista esteja ordenada pela ordem natural e que os elementos implementem Comparable.

List<Integer> sorted = new ArrayList<>(List.of(1, 3, 5, 7, 9, 11));
int idx = Collections.binarySearch(sorted, 7);
System.out.println("Found 7 at index: " + idx); // 3

int missing = Collections.binarySearch(sorted, 4);
System.out.println("4 not found, insertion point: " + (-missing - 1)); // 2

Comparable versus Comparator

Distinção principal:

  • Comparable: define a própria ordem natural da classe — uma por classe
  • Comparator: define uma ordenação externa — ilimitada e combinável

Prática: classificação

Uma classificação que usa Comparable para definir naturalmente a ordem decrescente das pontuações.

class LeaderboardEntry implements Comparable<LeaderboardEntry> {
    final String player;
    final int score;
    final long timestamp;

    LeaderboardEntry(String player, int score) {
        this.player = player; this.score = score;
        this.timestamp = System.nanoTime();
    }

    @Override
    public int compareTo(LeaderboardEntry other) {
        int scoreCmp = Integer.compare(other.score, this.score); // descending
        if (scoreCmp != 0) return scoreCmp;
        return Long.compare(this.timestamp, other.timestamp); // earlier = higher
    }

    @Override public String toString() { return player + ": " + score; }
}

TreeSet<LeaderboardEntry> board = new TreeSet<>();
board.add(new LeaderboardEntry("Alice", 950));
board.add(new LeaderboardEntry("Bob", 1200));
board.add(new LeaderboardEntry("Carol", 950));
board.forEach(System.out::println);
// Bob: 1200 / Alice: 950 / Carol: 950

Verificação rápida

O que compareTo() retorna quando o objeto atual é menor que o argumento?

Recapitulação: a interface Comparable

Principais aprendizados:

  • Implemente Comparable<T> para definir a ordem natural de uma classe
  • compareTo retorna um valor negativo (menor), zero (igual) ou positivo (maior)
  • Use Integer.compare()/Double.compare(): nunca subtraia, devido ao risco de estouro
  • Encadeie comparações para ordenar por vários campos: principal → secundário
  • A ordem natural é usada por Collections.sort, Arrays.sort, TreeSet e TreeMap
  • Comparable define UMA ordem; use Comparator para várias ordenações

Perguntas Frequentes

A aula “A Interface Comparable” é grátis?

Sim — o texto completo de “A Interface Comparable” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “A Interface Comparable”?

Implemente Comparable para dar a uma classe uma ordenação natural e use-a com Collections.sort. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “A Interface Comparable”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. A Interface Comparable
  2. Ordenação com Comparator e Lambdas
  3. Ordenação por Várias Chaves com thenComparing
  4. Ordenação de Matrizes e Coleções na Prática
← Voltar para Java Academy