Comparar variáveis: == ou .equals() ???

09/04/2009

37

Comparações com o método [b]equals[/b] e com o operador [b]==[/b] Resumindo antes para depois explicar.... equals --> Comparações dentro do Heap da JVM == --> Comparações fora do Heap da JVM
[b]O que é o Heap?[/b] O Heap é um local reservado e protegido da JVM (Java Virtual Machine) onde ficam alocados todos os objetos instanciados durante a execução de seu programa... cada um destes objetos possui um endereco de memoria onde está armazenado, e o unico acesso a ele, é por via de uma referencia (armazenada fora do heap).... Esta referencia, também possui o endereco de memoria, tornando o seu acesso unico e exclusivo a este objeto.
lembre-se que tipos primitivos (int, double, float) tambem ficam fora do HEAP com as referencias para objetos
**** Comparacao utilizando '==' **** quando voce usa o operador "==" para comparar.... voce está comparando [b]fora do heap[/b] Entao.... no caso disso:
int a = 1;
int b = 1;

if (a == b) {
   //instrucao
}
é uma comparacao externa ao heap da jvm, ou seja, vai comparar os tipos primitivos, ou seja, se o valor em 'a' eh o mesmo valor em 'b'... resultando é claro, em [b]true[/b] Já no caso da comparacao de OBJETOS, utilizando o '==' ficaria desta forma:
MeuObjeto obj1 = new MeuObjeto("Java");
MeuObjeto obj2 = new MeuObjeto("Free");

if (obj1 == obj2) {
   //instrucao
}
Ai voce está comparando os objetos fora do heap, ou seja, comparando apenas suas referencias....... Resultando na seguinte pergunta para a jvm em tempo de execucao:
[b]"A referencia obj1 aponta para um objeto no Heap, e a referencia obj2 tambem aponta para um objeto no Heap, esses 2 objetos, [u]SAO O MESMO OBJETO[/u]?"[/b]
Ai a jvm obviamente vai retornar false, pq cada um eh um objeto ("java" != "free")... agora no caso:
MeuObjeto obj1 = new MeuObjeto("Lucas");
MeuObjeto obj2 = obj1;
O que eu fiz, foi instanciar um novo "MeuObjeto" (dentro do heap) e apontar obj1 (fora do heap) para ele.... depois criei uma nova referencia (fora do heap) chamada obj2, e apontei para obj1... ou seja... para o mesmo objeto..... exemplo de que eh o mesmo objeto, se eu fizer:
System.out.println(   obj2.getNome()    );
provavelmente eu teria a saida: Lucas :o :o Continuando com esse exemplo, se eu efetuasse a comparacao, ficaria assim:
if (ob1 == obj2) {
   //instrucao
}
Ai sim, a saida seria [b]true[/b] pois a referencia aponta para o mesmo objeto.... **** Comparacao utilizando 'equals'' **** É o [i]_inverso_[/i] da '==' compara os objetos dentro do heap, ou seja.... suas caracteristicas... um exemplo básico e auto-explicativo seria.....
String nome1 = "Lucas";
String nome2 = "Jose";

if (nome1.equals(nome2)) {
   //isntrucao
}
Ai sim, seria false, pois o VALOR das 2 sao diferentes... Por isso que é ideal quando criamos (minha opiniao) um novo objeto, do tipo por exemplo, PESSOA, sobrescrevermos o metodo 'equals' herdado de Object..... para podermos ver se as pessoas sao iguais..... exemplo básico e tosco:
public class Pessoa extends Object implements Serializable {
   private int idade;
   private String nome;

   public Pessoa() {
      setIdade(0);
      setNome("Alguem");
   }

   public void setIdade(int i) {
      if (idade < 0) throw new RuntimeException("Idade Negativa");
      else this.idade = i;
   }

   public void setNome(String n) {
      //checo se a referencia para o nome existe...
      if (n == null) throw new RuntimeException("Nome Invalido");
      else this.nome = n;
   }

   public String getNome() {
      return nome;
   }

   public int getIdade() {
      return idade;
   }

   public boolean equals(Pessoa p) {
      boolean ret = false;

      if (   (this.nome.equals(p.getNome())) && (this.idade == p.getIdade())   )
         ret = true;

      return ret;
   }
}
O ideal seria também uma implementação do metodo hashcode, mas fica para a próxima.... :!: :!: :!: Deu pra entender???? Abraços a todos do JF! :!: :!: :!: :!: :!: :!: :o :o :o :!: :!: :metal:
Responder

Posts

09/04/2009

Felipe Caldas

Muito bom, parabéns ;) :!:
Responder

09/04/2009

Lupus_ragabash

agora q vc vai dizer isso ?:?? ahuauhauh dps de eu ficar quebrando a cabeça lá !! :idea:
Responder

09/04/2009

Lupus_ragabash

[quote="Lupus_Ragabash"]agora q vc vai dizer isso ?:?? ahuauhauh dps de eu ficar quebrando a cabeça lá !! :idea:
Hehehehehehe... se tivesse varrido as dicas antes Lupus! Isso tá ai faz tempoooooo :!: Valeu cara!
Responder

09/04/2009

Vapavan

tenho duvida em como definir classe e metodos
Responder

09/04/2009

Vonlinkerstain

Sobrou uma duvidasinha Object ob = new Objetc{"Java"}; Object ob2 = new Objetc{"Java"}; if (ob==ob2) verdadeiro ou falso?
Responder

09/04/2009

Lucas Teixeira

[quote="vonlinkerstain"]Sobrou uma duvidasinha Object ob = new Objetc{"Java"}; Object ob2 = new Objetc{"Java"}; if (ob==ob2) verdadeiro ou falso?
Hum.... que construtor maluco é esse ai? :arrow:
Responder

09/04/2009

Vonlinkerstain

Só uma curiosidade besta... supondo que tenha dois objetos iguais, construidos em diferentes partes do programa, qual seria a resposta para isso? Object ob = new Objetc{"Java"}; Object ob2 = new Objetc{"Java"}; if (ob==ob2) verdadeiro ou falso?
Responder

09/04/2009

Vaklav Ravel

[quote="vonlinkerstain"]Só uma curiosidade besta... supondo que tenha dois objetos iguais, construidos em diferentes partes do programa, qual seria a resposta para isso? Object ob = new Objetc{"Java"}; Object ob2 = new Objetc{"Java"}; if (ob==ob2) verdadeiro ou falso?
Sem levar em conta a corretude de seu código, considerando que new Object(String arg) seja um construtor qualquer, o resultado da igualdade é Falso, Pois apontam pra "áreas de memória" diferentes Mas caso o método equals de seu Object fictício compare o valor de args passado no construtor, então a igualdade:
ob.equals(ob2)
é Verdadeira, como está muito bem explicado pelo Lucas.
Responder

09/04/2009

Vonlinkerstain

Hum interessante... Isso foi o que eu fiquei em dúvida... Se ele só comparava pelo endereçamento ou não.. Legal. P.S. Não implementei nada parecido, só tinha isso como uma dúvida técnica
Responder

09/04/2009

Camila Bastos

public static void main(String[] args) { String s = new String("Camila"); String s2 = new String("Camila"); if(s.equals(s2)) { System.out.println("s.equals(s2)"); //retorna true } if (s == s2) { System.out.println("s == s2"); //retorna false } String s3 = "Camila"; String s4 = "Camila"; if(s3.equals(s4)) { System.out.println("s3.equals(s4)"); //retorna true } if (s3 == s4) { System.out.println("s3 == s4"); //retorna true } } Pq quando eu uso String s3 = "Camila"; ele retorna os if = true e uso String s = new String("Camila"); só o if com equals ele retorna true... alguém poderia me dizer??????? :wink: bigada
Responder
pq existe um pool de string em java. quando vc instancia strings assim:
// como ainda não existe nenhuma instacia da string "Camila" no pool  
// é criado uma e faz s3 refrenciar a ela.
String s3 = "Camila";

// aqui já existe uma instancia de "Camila" no pool de strings então 
//  s4 passa tb referenciar a mesma instancia.
String s4 = "Camila";
hehehe isso é para poupar recursos da maquina. =* beijos!
Responder

09/04/2009

Luiz Pereira

Pq String tem um comportamento especial, são mantidas em um pool e são imutáveis. Por causa do pool todas as variáveis string com mesmo valor apontam para a mesma string em memória mas quando vc utiliza a construção:
String s = new String(  "texto" );
vc força a criação da string fora do pool e consequentemente em outro endereço de memória. Por isso o teste com equals retorna verdadeiro e o teste com == que testa o endereço de memória retorna falso. flw
Responder
          String nome = "victor";
          nome = "hugo";
          nome = "victor hugo";

na 1º linha deste trecho, é criado uma referencia para o objeto string e tambem o objeto com valor de "victor". Na 2º linha a JVM faz da variavel string nome (ou referencia de memoria do objeto), um stringbuffered chamado nome que aponta para o novo objeto de valor "hugo". Na 3º linha o objeto de valor "hugo" recebe agora o valor "victor hugo" e o carbage collector se encarrega de destruir os demais objetos. a classe string não é capaz de alterar o seu conteúdo por isso a JVM cria um stringbuffered quando verifica que a muitas alterações nesse objeto
Responder

08/10/2009

Bruno Melo

Muito bom o POST, muita gente como eu mesmo, nao sabia definir muito bem quando utilizar if ( == ) {} ou quando utilizar x.equals(y) ... Parabens pelo topico ! abraço !
Responder

15/02/2010

Daniel Lagares

Muito bom esse post, só que ainda fiquei com uma dúvida: String a = "x"; String b = "y"; if(a+b == a+b) retorna false. lguém pode me dar um help? :mrgreen:
Responder
×
+1 DevUP
Acesso diário, +1 DevUP
Parabéns, você está investindo na sua carreira