[Resolvido] Um Set não aceita elementos iguais perante == ou .equals?
11 respostas
FredericoGenovez
Tenho um código com comportamento estranho:
publicclassTeste{publicstaticvoidmain(String[]args){Set<Conta>contas=newLinkedHashSet<>();Contac1=newConta();Contac2=newConta();c1.nome="a";c2.nome="a";System.out.println(contas.add(c1));//imprime trueSystem.out.println(contas.add(c2));//imprime true novamente mesmo com os elementos sendo iguais, e eu implementei o metódo equals...System.out.println("Eles são .equals ? "+c1.equals(c2));//imprime trueSystem.out.println("Eles são == ?"+(c1==c2));//imprime false}}classConta{Stringnome;publicbooleanequals(Objecto){if(oinstanceofConta)if(((Conta)o).nome.equals(this.nome))returntrue;returnfalse;}}
??? Como consegui inserir dois elementos (equals) em um Set? o Set verifica igualdade de referências ???
System.out.println("Eles são .equals ? "+c1.equals(c2));//imprime true
O trecho acima imprime true pois o equals compara o conteudo…
System.out.println("Eles são == ?"+(c1==c2));//imprime false
O trecho acima imprime false pois == esta comparando a referencia dos objetos…
FredericoGenovez
A dúvida é, um Set permite a inserção de objetos Iguais? Se não permite porque no código que eu postei consegui inseri dois objetos iguais?? Para o Set os Objetos são iguais (==) ou iguais (equals) ???
gustavocoolt
Os objetos foram considerados diferentes pelo operador ==, embora contenham conteudos idênticos, pois a referência aos objetos na memória heap é diferente.
FredericoGenovez
Eu sei disso, a pergunta é a seguinte, em um conjunto Set eu não posso adicionar elementos iguais pois o um Set é uma representação dos conjuntos numéricos, mais se meus objetos são iguais, mesmo que não ocupem o mesmo espaço na memória o Set não vai os considerar iguais? ele usa a comparação por referências e não o metódo equals? tem algo errado aí pois se ele fosse usar a igualdade por referências não iria haver a necessidade do metódo equals se chamar equals, pois se ele se chama equals em Object e eu reescrevo e para que os frameworks e bibliotecas o chamem se não eu poderia criar meu proprio método de igualdade…
Eu estou fazendo uns testes aqui com a classe String por exemplo funcionou normalmente ele compara se os elementos são iguais com o metódo equals, mas na minha classe ainda não consegui achar o problema…
FredericoGenovez
Veja outro exemplo do problema…
importjava.util.Set;importjava.util.HashSet;publicclassTeste{publicstaticvoidmain(String[]args){Set<A>as=newHashSet<>();Aa=newA();Ab=newA();Ac=newA();a.nome="A";b.nome="A";c.nome="c";System.out.println(a.equals(b));//Imprime true mais se eles são iguais como nas linhas abaixo eu adiciono os dois na coleção?System.out.println(as.add(a));System.out.println(as.add(b));System.out.println(as.add(c));}}classA{Stringnome;publicbooleanequals(Objecto){return((A)o).nome.equals(this.nome);}}
jamirdeajr
Olá,
Você precisa fazer override do hashcode... O add do set vai chamar ele para fazer a comparação...
É isso mesmo, funcionou aqui agora, vou dar umas estudada no método hashCode, pois não sabia que o Set usava ele na comparação, você sabe me explicar o motivo do uso dele para comparação?
FredericoGenovez
Achei uma explicação, obrigado ai a ajuda gente…
gustavocoolt
O hashCode é um método que retorna um código hash de um objeto… assim é definido que posição que o objeto será salvo, se outro objeto chegar na posição ja salva, ele substitui.
OBS: Ele nao precisa percorrer toda a lista verificando… ele vai direto na posição que o hash retornou, ganhando performance.
jamirdeajr
Acho que a melhor explicação está no livro Effective Java, que copio aqui em uma tradução livre:
“Item 9: Sempre sobrescreva hasCode quando sobrescrever equals
Uma fonte comum de bugs é o esquecimento de fazer override do método hashCode. Você precisa sobrescrever o hashCode em toda classe que sobrescrever equals.
Não fazer resultará na violação do contrato geral para Object.hashCode, que fará com que sua classe não funcione corretamente em conjunto com as coleções baseadas em hash, incluindo HashMap, HashSet e HashTable.”