Qual a diferença entre equals() e == em Java?

O operador == compara referências de memória, enquanto o método equals() verifica a igualdade de conteúdo entre objetos em Java.

Qual a diferença entre equals() e == em Java?

Em Java, tanto equals() quanto == são usados para comparações, mas possuem diferenças fundamentais na forma como operam:

  • == compara referências de memória (se os dois objetos são o mesmo na memória).
  • equals() compara conteúdos dentro dos objetos (se dois objetos possuem os mesmos valores).

1. Comparação com == (Referência de Memória)

O operador == verifica se duas variáveis referenciam o mesmo objeto na memória.

class Pessoa {
    String nome;

    Pessoa(String nome) {
        this.nome = nome;
    }
}

public class TesteIgualdade {
    public static void main(String[] args) {
        Pessoa p1 = new Pessoa("João");
        Pessoa p2 = new Pessoa("João");

        System.out.println(p1 == p2); // false, pois são objetos diferentes na memória
    }
}

Saída esperada:

false

Mesmo que p1 e p2 tenham o mesmo valor de nome, == retorna false porque p1 e p2 são objetos diferentes na memória.

2. Comparação com equals() (Conteúdo dos Objetos)

Por padrão, o método equals() verifica se duas referências apontam para o mesmo objeto, assim como ==. Porém, ao sobrescrever equals(), podemos personalizar a comparação.

class Pessoa {
    String nome;

    Pessoa(String nome) {
        this.nome = nome;
    }

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

Agora, comparando equals():

public class TesteEquals {
    public static void main(String[] args) {
        Pessoa p1 = new Pessoa("João");
        Pessoa p2 = new Pessoa("João");

        System.out.println(p1.equals(p2)); // true, pois os nomes são iguais
    }
}

Saída esperada:

true

Aqui, equals() verifica o conteúdo da variável nome, retornando true quando os valores são iguais.

3. Comparação com Strings

Strings são tratadas de forma especial em Java, pois são armazenadas no pool de Strings. Assim, == pode retornar true quando duas Strings com o mesmo conteúdo referenciam o mesmo local na memória.

public class TesteStrings {
    public static void main(String[] args) {
        String s1 = "Java";
        String s2 = "Java";
        String s3 = new String("Java");

        System.out.println(s1 == s2); // true (referência ao mesmo objeto no pool de Strings)
        System.out.println(s1 == s3); // false (s3 é um novo objeto)
        System.out.println(s1.equals(s3)); // true (conteúdo igual)
    }
}

Saída esperada:

true
false
true

4. Resumo das Diferenças entre == e equals()

Comparação == (Operador de Igualdade) equals() (Método)
O que compara? Referência na memória Conteúdo do objeto
Pode ser sobrescrito? Não Sim
Funciona bem para objetos? Não Sim, se bem implementado
Uso comum Comparação de primitivas e referências Comparação de conteúdo

5. Boas Práticas ao Comparar Objetos

  • Use == apenas para comparar tipos primitivos (int, double, boolean, etc.).
  • Para comparar objetos, sempre utilize equals(), especialmente em classes personalizadas.
  • Ao trabalhar com Strings, sempre use equals(), pois == pode gerar resultados inesperados.

Conclusão

O operador == verifica se duas variáveis apontam para o mesmo objeto na memória, enquanto equals() compara o conteúdo dos objetos. Para garantir comparações precisas, é essencial sobrescrever equals() corretamente em classes personalizadas.

O uso incorreto de equals() e == pode gerar erros difíceis de identificar em aplicações Java. Um exemplo clássico acontece ao comparar objetos em coleções, como Set e Map, onde a implementação de equals() e hashCode() é fundamental para garantir a correta identificação e armazenamento dos elementos. Além disso, ao trabalhar com Strings, confiar no operador == pode levar a bugs inesperados, especialmente ao lidar com valores obtidos de entrada do usuário ou consultas a bancos de dados.

Algumas aplicações:

  • Comparação de objetos em coleções como List, Set e Map
  • Verificação de identidade de objetos em sistemas grandes
  • Validação de dados entre objetos no banco de dados
  • Comparação segura de Strings recebidas como entrada

Dicas para quem está começando

  • Use == apenas para comparar tipos primitivos
  • Sempre sobrescreva equals() ao comparar objetos personalizados
  • Prefira equals() para comparar Strings em vez de ==
  • Ao sobrescrever equals(), também sobrescreva hashCode() para evitar problemas em coleções
  • Pratique criando classes e comparando objetos para entender melhor as diferenças

Contribuições de Rodrigo Farias

Compartilhe este tutorial: Qual a diferença entre equals e == em Java

Compartilhe este tutorial

Continue aprendendo:

O que é um método estático e quando usá-lo

Um método estático em Java pertence à classe e não a uma instância específica, podendo ser chamado sem a necessidade de criar um objeto.

Tutorial anterior

Como criar métodos genéricos em Java

Métodos genéricos em Java permitem criar funções que podem operar em diferentes tipos de dados, tornando o código mais reutilizável e flexível.

Próximo tutorial