Da trilha de Java Este conceito ainda não saiu como card do dia. ir para o card de hoje

Java POO Intermediário

equals e hashCode

Em Java, os métodos equals e hashCode definem como objetos são comparados e armazenados em coleções baseadas em hash, como HashMap e HashSet. O contrato de equals exige reflexividade, simetria, transitividade, consistência e que x.equals(null) seja false. O contrato de hashCode diz que objetos iguais devem ter o mesmo hash, e que o hash deve ser consistente durante a execução.

Quando você sobrescreve equals, deve sobrescrever hashCode. Caso contrário, objetos iguais podem acabar em baldes diferentes, quebrando o funcionamento de HashSet e HashMap. A classe Objects oferece Objects.equals e Objects.hash para facilitar a implementação correta e evitar NullPointerException.

Armadilhas comuns incluem usar == em vez de equals, esquecer de sobrescrever hashCode, usar campos mutáveis como base para o hash e confundir equals com comparação de referências. Entender esses detalhes é essencial para escrever código robusto com coleções.

Pontos-chave

  • O contrato de equals exige reflexividade, simetria, transitividade, consistência e x.equals(null) == false.
  • Objetos iguais por equals devem ter o mesmo hashCode.
  • HashSet e HashMap usam hashCode para localizar o balde e equals para confirmar a igualdade.
  • Objects.equals e Objects.hash simplificam a implementação e tratam null com segurança.
  • Nunca use campos mutáveis no cálculo de hashCode se o objeto for chave de coleção.
EqualsHashCodeDemo.java
import java.util.*;

class Pessoa {
    private final String nome;
    private final int idade;

    Pessoa(String nome, int idade) {
        this.nome = nome;
        this.idade = idade;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Pessoa pessoa = (Pessoa) o;
        return idade == pessoa.idade && Objects.equals(nome, pessoa.nome);
    }

    @Override
    public int hashCode() {
        return Objects.hash(nome, idade);
    }

    @Override
    public String toString() {
        return nome + " (" + idade + ")";
    }
}

public class EqualsHashCodeDemo {
    public static void main(String[] args) {
        Pessoa p1 = new Pessoa("Ana", 30);
        Pessoa p2 = new Pessoa("Ana", 30);

        System.out.println("p1.equals(p2): " + p1.equals(p2));
        System.out.println("p1.hashCode() == p2.hashCode(): " + (p1.hashCode() == p2.hashCode()));

        Set<Pessoa> conjunto = new HashSet<>();
        conjunto.add(p1);
        conjunto.add(p2);
        System.out.println("Tamanho do HashSet: " + conjunto.size());

        Map<Pessoa, String> mapa = new HashMap<>();
        mapa.put(p1, "Primeira");
        mapa.put(p2, "Segunda");
        System.out.println("Valor no HashMap: " + mapa.get(p1));
    }
}

Exercícios

  1. 1
    Fácil

    Implemente equals e hashCode para Ponto

    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.

    Resolver
  2. 2
    Médio

    Chave composta em HashMap

    Crie uma classe Chave que representa uma chave composta por dois campos String. Sobrescreva equals e hashCode corretamente. Use essa chave em um HashMap para associar a um valor inteiro. Teste inserir duas chaves iguais e verificar que o valor é sobrescrito.

    Resolver
  3. 3
    Desafio

    Igualdade com herança e campo mutável

    Crie uma hierarquia com uma classe base Animal e uma subclasse Cachorro. A classe Animal tem um campo nome (String) e a subclasse adiciona raca (String). Implemente equals e hashCode de forma que um Cachorro só seja igual a outro Cachorro com mesmo nome e raça, e nunca igual a um Animal que não seja Cachorro. Além disso, crie um HashSet de Animal e demonstre que a igualdade funciona corretamente. Depois, torne o campo nome mutável e mostre o problema de usá-lo como chave em um HashMap após a mutação.

    Resolver

Continue estudando