public class Teste{
public static void main(String [] args){
Set<Conta> contas = new LinkedHashSet<>();
Conta c1 = new Conta();
Conta c2 = new Conta();
c1.nome = "a";
c2.nome = "a";
System.out.println(contas.add(c1));//imprime true
System.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 true
System.out.println("Eles são == ?"+(c1 == c2));//imprime false
}
}
class Conta{
String nome;
public boolean equals(Object o){
if(o instanceof Conta)
if(((Conta)o).nome.equals(this.nome))
return true;
return false;
}
}
??? Como consegui inserir dois elementos (equals) em um Set? o Set verifica igualdade de referências ???
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) ???
Os objetos foram considerados diferentes pelo operador ==, embora contenham conteudos idênticos, pois a referência aos objetos na memória heap é diferente.
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…
import java.util.Set;
import java.util.HashSet;
public class Teste{
public static void main(String [] args){
Set<A> as = new HashSet<>();
A a = new A();
A b = new A();
A c = new A();
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));
}
}
class A{
String nome;
public boolean equals(Object o){
return ((A)o).nome.equals(this.nome);
}
}
[quote=jamirdeajr]Olá,
Você precisa fazer override do hashcode… O add do set vai chamar ele para fazer a comparação…
[code]class Conta{
String nome;
@Override
public boolean equals(Object o){
if(o instanceof Conta)
if(((Conta)o).nome.equals(this.nome))
return true;
return false;
}
@Override
public int hashCode() {
return nome.hashCode();
}
} [/code] [/quote]
É 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?
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.
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.”