O Método Equals em Java: Comparando Conteúdo, Não Referências
- #Java
Se você já teve contato com alguma linguagem de programação, sabe que, para comparar valores de variáveis diferentes, utilizamos uma estrutura condicional e um operador. Como no exemplo abaixo, onde estou verificando se o conteúdo da variável x é igual ao conteúdo da variável y, feito em Python:
variavel1 = "Diego"
variavel2 = "Diego"
if variavel1 == variavel2:
return true
return false
Fazendo uma breve análise sobre este código, podemos afirmar que o retorno dessa função será True, visto que o conteúdo de ambas variáveis é idêntico, e essa afirmação está correta.
Vamos analisar de forma técnica como isso está acontecendo.
Ao declararmos uma variável em Python, o que está acontecendo é que estamos criando um objeto String na memória e armazenando o conteúdo informado pelo programador. Por padrão, precisamos definir o nome dessa variável, que será utilizado como forma de caminho na memória. Na ilustração abaixo, podemos compreender melhor esse comportamento.
Quando tentamos repetir o mesmo código em Java, nos deparamos com um comportamento estranho
String variavel1 = new String("hello");
String variavel2 = new String("hello");
if (variavel1 == variavel2) {
return true;
}
return false;
}
O motivo pelo qual afirmei ser estranho é que o retorno dessa comparação é false!
Mas como assim? Ambas as variáveis têm o mesmo conteúdo, certo? Sim, está correto, porém, em Java, o comportamento informado anteriormente sobre como nosso objeto é armazenado na memória ocorre de maneira diferente. Vamos entender.
Como vimos em Python, nossa variável está diretamente relacionada com o conteúdo na memória. Então, quando chamamos o nome da variável em nossa IDE, estamos acessando diretamente o conteúdo na memória.
O que é diferente em Java, pois quando chamamos nossa variável, o que está acontecendo nos bastidores é que estamos chamando um valor de referência no qual nosso objeto está armazenado na memória. Segue a ilustração:
Esse é o principal motivo pelo qual nossa comparação retornou false. Isso acontece porque, na realidade, não estamos comparando o conteúdo das variáveis, mas sim os valores de referência na memória.
Vamos utilizar um exemplo mais simples para compreendermos melhor esses comportamentos.
No caso, vamos imaginar que um entregador precisa entregar um produto para um determinado cliente e para isso precisa passar por um túnel. Entenda esse túnel como nossa variável.
Primeiramente, vamos simular esse exemplo utilizando como base o Python:
O entregador tem um túnel à sua frente, e o destino final desse túnel tem exatamente a casa do nosso cliente. Logo, conseguimos acessar a casa do cliente e entregar seu produto.
Agora, usando Java como base para o nosso exemplo:
O nosso entregador está na mesma situação anterior, porém o túnel não tem exatamente o endereço do nosso cliente, mas sim o endereço da sua cidade. Logo, para acessarmos a casa do nosso cliente, primeiramente temos que passar pela cidade do cliente que contém o endereço correto de sua casa. Assim, podemos entregar seu produto.
Espero que dessa forma, tenha compreendido melhor a diferença entre essas duas situações.
Certo, mas como podemos ajudar o nosso entregador a ter acesso direto à casa do nosso cliente? É aqui que nosso método "equals" entra para nos ajudar nessa missão!
O método equals do Java é um método booleano que recebe uma String como parâmetro. Sua funcionalidade é comparar o valor do conteudo do objeto no qual está sendo chamado com o valor que está recebendo em seu parâmetro.
Note que o método equals não está comparando o valor de referência, mas sim o conteúdo do objeto.
public class Main {
public static void main(String[] args) {
String variavel = new String("Diego");
System.out.println(variavel.equals("Diego")); // Nesse código, o método equals está acessando o valor "Diego" da variável...
// e comparando se é igual ao "Diego" que está sendo passado como parâmetro.
// Logo seu retorno é true!
}
}
Entenda nosso método "equals" como um atalho para nosso entregador, dessa forma, no final desse atalho, chegamos à casa do seu cliente.
Agora vamos refatorar nosso código anterior em Java:
String str1 = new String("hello");
String str2 = new String("hello");
if (str1.equals(str2)) {
return true;
}
return false;
}
Dessa forma, temos o nosso resultado "true" esperado, e finalmente conseguimos finalizar esse código corretamente.
Observação:
Atualmente em Java, não precisamos fazer a instanciação de uma variável do tipo String, basta apenas definir o tipo da variável e o seu valor. Dessa forma, temos um comportamento um pouco diferente do que abordei no artigo, envolvendo o POOL DE STRINGS, que posso abordar em outro artigo. Mas é importante ressaltar que, mesmo assim, ainda é necessário utilizar o método equals pelos mesmos motivos anteriores.
private static boolean teste() {
String str1 = "hello";
String str2 = "hello";
return str1.equals(str2);
}
Conclusão:
A forma como acessamos Strings em Java é um pouco diferente de outras linguagens, dado que nossa variável não é o caminho direto para o objeto em memória, mas sim um valor de referência utilizado para acessar o objeto em si.
Fontes:
https://codegym.cc/pt/quests/lectures/pt.questsyntaxpro.level07.lecture02
https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-