Fácil Java

Implemente equals e hashCode para Ponto

Enunciado

Crie uma classe Ponto com coordenadas x e y (inteiros). Sobrescreva equals e hashCode para que dois pontos sejam iguais se tiverem as mesmas coordenadas. Teste a igualdade e o uso em um HashSet.

Requisitos

  • A classe Ponto deve ter os campos x e y.
  • equals deve comparar os valores de x e y.
  • hashCode deve ser consistente com equals.
  • O programa deve imprimir se dois pontos iguais são considerados iguais e o tamanho de um HashSet contendo ambos.

Código inicial

import java.util.*;

class Ponto {
    private int x, y;

    Ponto(int x, int y) {
        this.x = x;
        this.y = y;
    }

    // TODO: sobrescreva equals e hashCode
}

public class Main {
    public static void main(String[] args) {
        Ponto p1 = new Ponto(1, 2);
        Ponto p2 = new Ponto(1, 2);

        System.out.println("Iguais? " + p1.equals(p2));
        Set<Ponto> set = new HashSet<>();
        set.add(p1);
        set.add(p2);
        System.out.println("Tamanho do set: " + set.size());
    }
}

Saída esperada

Iguais? true
Tamanho do set: 1
Ver dica

Use Objects.equals para comparar campos e Objects.hash para gerar o hash.

Mostrar solução
import java.util.*;

class Ponto {
    private int x, y;

    Ponto(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Ponto ponto = (Ponto) o;
        return x == ponto.x && y == ponto.y;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}

public class Main {
    public static void main(String[] args) {
        Ponto p1 = new Ponto(1, 2);
        Ponto p2 = new Ponto(1, 2);

        System.out.println("Iguais? " + p1.equals(p2));
        Set<Ponto> set = new HashSet<>();
        set.add(p1);
        set.add(p2);
        System.out.println("Tamanho do set: " + set.size());
    }
}

Passo a passo

  1. Definimos a classe Ponto com dois campos inteiros x e y.
  2. No método equals, primeiro verificamos se é a mesma referência (this == o). Se for, retornamos true imediatamente.
  3. Em seguida, verificamos se o é null ou se a classe é diferente. Se for, retornamos false.
  4. Fazemos o cast para Ponto e comparamos os valores de x e y com ==.
  5. No hashCode, usamos Objects.hash(x, y) para gerar um código baseado nos mesmos campos usados em equals.
  6. No main, criamos dois pontos iguais e verificamos equals e o comportamento em um HashSet.

Por que funciona

O contrato de equals e hashCode é respeitado: dois objetos iguais têm o mesmo hash, então o HashSet os considera iguais e armazena apenas um. Isso ocorre porque o HashSet usa hashCode para encontrar o balde e equals para confirmar a igualdade.

Erros comuns

  • Esquecer de sobrescrever hashCode: se apenas equals for sobrescrito, o HashSet pode conter duplicatas porque os hashes serão diferentes. Exemplo: set.add(p1); set.add(p2); resultaria em tamanho 2.
  • Usar == para comparar objetos: p1 == p2 compara referências, não valores. Use equals.
  • Não tratar null: o.equals(null) deve retornar false, mas se você não verificar, pode lançar NullPointerException.

Outra forma de resolver

Usar record (Java 16+), que gera automaticamente equals e hashCode:

record Ponto(int x, int y) {}

Isso é preferível quando a classe é imutável e serve apenas como portadora de dados.

Saída esperada

Iguais? true
Tamanho do set: 1