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

Java

09/04/2009

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:
Lucas Teixeira

Lucas Teixeira

Curtidas 0

Respostas

Felipe Caldas

Felipe Caldas

09/04/2009

Muito bom, parabéns ;) :!:
GOSTEI 0
Lupus_ragabash

Lupus_ragabash

09/04/2009

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

Lupus_ragabash

09/04/2009

[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!
GOSTEI 0
Vapavan

Vapavan

09/04/2009

tenho duvida em como definir classe e metodos
GOSTEI 0
Vonlinkerstain

Vonlinkerstain

09/04/2009

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

Lucas Teixeira

09/04/2009

[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:
GOSTEI 0
Vonlinkerstain

Vonlinkerstain

09/04/2009

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?
GOSTEI 0
Vaklav Ravel

Vaklav Ravel

09/04/2009

[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.
GOSTEI 0
Vonlinkerstain

Vonlinkerstain

09/04/2009

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
GOSTEI 0
Camila Bastos

Camila Bastos

09/04/2009

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
GOSTEI 0
Daniel Carrazzoni

Daniel Carrazzoni

09/04/2009

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!
GOSTEI 0
Luiz Pereira

Luiz Pereira

09/04/2009

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
GOSTEI 0
Daniel Carrazzoni

Daniel Carrazzoni

09/04/2009

          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
GOSTEI 0
Bruno Melo

Bruno Melo

09/04/2009

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 !
GOSTEI 0
Daniel Lagares

Daniel Lagares

09/04/2009

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:
GOSTEI 0
Carlos Heuberger

Carlos Heuberger

09/04/2009

[quote="lakabeny"]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:
Pergunta bastante comum... Para objetos o "==" somente compara se se trata da mesma instância (mesma posição na memória), ele não compara o conteúdo. No seu código, são criadas duas instâncias distintas (apesar de terem o mesmo conteúdo). Para comparar o conteúdo deve-se usar o método [b]equals()[/b]. por isso sempre se deve comparar Strings com o equals():
if ((a+b).equals(a+b))
* para isso funcionar com um determinado objeto ele deve sobrescrever o método equals() conforme necessário. Caso contrário o equals() do Object é usado, que faz um simples "==". []]
GOSTEI 0
Adriano Soares

Adriano Soares

09/04/2009

[quote="camilasmbastos"]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
Oi Camila ... Porque assim, quando voce usa o equals ele esta se referenciando ao valor que voce deu para o S e o S2, ao contrario de == que voce ja esta comparando as referencias de S e S2 e nao valores. Certo espero ter ajudado.
GOSTEI 0
Marcos Biasibetti

Marcos Biasibetti

09/04/2009

alguem sabe dizer pq nao funfa javascript:parent.emoticon(':neutral:') package javaapplication20; import javax.swing.JOptionPane; public class JavaApplication20 { public static void main(String[] args) { String frase; frase = JOptionPane.showInputDialog("iforme uma frase"); String palavra = (unipar) ; if (frase.equals(palavra)){ JOptionPane.showMessageDialog(null,"a frase contem a palavra unipar"); } else { JOptionPane.showMessageDialog(null,"a frase nao contem a palavra unipar"); } } } :neutral:
GOSTEI 0
Wanderson Brito

Wanderson Brito

09/04/2009

E se eu tiver um atributo da classe pra comparar com um inteiro ex: If (time.posicao == 1){ Time.campeao = true; Time.libertadores = true; Time.rebaixado = false; Time.sulAmericana = false; } isso funcionaria? ou eu deveria usar a função pra comparar?
GOSTEI 0
Adriano Soares

Adriano Soares

09/04/2009

[quote="wandersoncstd9"]E se eu tiver um atributo da classe pra comparar com um inteiro ex: If (time.posicao == 1){ Time.campeao = true; Time.libertadores = true; Time.rebaixado = false; Time.sulAmericana = false; } isso funcionaria? ou eu deveria usar a função pra comparar?
se posicao for um "int", sim, vai funcionar.
GOSTEI 0
POSTAR