Quais as interfaces necessárias a classe precisa implementar para que possa ser usada num HashSet, evitando objetos repetidos.
A classe em questao chama-se Habilidade e se o campo codHabilidade for igual considera-se o objeto igual.
Eu ja implementei o metodo equals retornando true se os codHabilidade dos objetos comparados forem iguais, já implementei a interface Comparable (método compareTo retornando 0 caso os codHabilidade sejam iguais), e ainda está colocando elementos repetidos no HashSet.
Cara… não entendi seu problema não! Tente explicar melhor…
No aguardo…
T
thingol
hill:
Quais as interfaces necessárias a classe precisa implementar para que possa ser usada num HashSet, evitando objetos repetidos.
A classe em questao chama-se Habilidade e se o campo codHabilidade for igual considera-se o objeto igual.
Eu ja implementei o metodo equals retornando true se os codHabilidade dos objetos comparados forem iguais, já implementei a interface Comparable (método compareTo retornando 0 caso os codHabilidade sejam iguais), e ainda está colocando elementos repetidos no HashSet.
Um HashSet é um HashMap onde chave == valor.
Para inserir elementos em um HashSet você precisa implementar corretamente public boolean equals (Object o) e public int hashCode(). Não é preciso implementar Comparable.
renatosilva
thingol:
Um HashSet é um HashMap onde chave == valor.
Huh? Não entendi. Não é o HashMap que usa um HashSet para guardar chaves? Aí um HashSet é um HasMap, que usa um HashSet, que é um HashMap, que usa um HashSet, que é um…
Hill, posta teu equals e hashCode ae…
T
thingol
renato3110:
thingol:
Um HashSet é um HashMap onde chave == valor.
Huh? Não entendi. Não é o HashMap que usa um HashSet para guardar chaves? Aí um HashSet é um HasMap, que usa um HashSet, que é um HashMap, que usa um HashSet, que é um…
Bom, eu fui pela descrição do Javadoc (This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.).
Vou dar uma olhada no fonte das duas classes para ver o que veio primeiro, o ovo (HashSet) ou a galinha (HashMap).
T
thingol
publicclassHashSetextendsAbstractSetimplementsSet,Cloneable,java.io.Serializable{staticfinallongserialVersionUID=-5024744406713321676L;privatetransientHashMapmap;// Dummy value to associate with an Object in the backing MapprivatestaticfinalObjectPRESENT=newObject();/** * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has * default initial capacity (16) and load factor (0.75). */publicHashSet(){map=newHashMap();}
Aham, nem o ovo nem a galinha - talvez um biscoito e uma jarra de biscoitos; a implementação da Sun de um HashSet contém um HashMap (ele não é um HashMap).
renatosilva
Que louco isso. Mas o HashMap não contém um HashSet também? Tô sem o fonte do JDK…
hill
Desculpe, não entendi o porque de implementar o metodo int hashCode. Como acontece essa distinção entre objetos quando sao colocados no Set ? Não eh através do metodo boolean equals(Object o) ? Porque se fosse assim, da forma como esta implementado o equals, duas Habilidade com codHabilidade iguais não poderiam ser inseridas, não eh mesmo ? E como é feita a implementação do método int hashCode nessa lógica simples do meu problema ?
Porque quando você precisa pesquisar seus objetos, que por um acaso estão armazenados numa estrutura de dados chamada tabela de hash,
o hashCode() agiliza a busca, ou faz ela não funcionar…
Seus Habilidade iguais devem estar sendo colocados no set porque retornam hash codes diferentes para objetos iguais.
Seu equals pode ser melhorado. Resumindo, o hash code deve retornar um número baseado na identidade do objeto, ou seja, baseado no equals(). Repita isso como um mantra:
Ao alterar equals(), provavelmente você precisa fazer o mesmo com hashCode().
Eu tava escrendo um texto sobre isso, talvez ano que vem tenha algo pronto :mrgreen: Você tá precisando ler um material sobre igualdade de objetos em Java, incluindo o equals() e o hashCode().
Tinha um tópico maneiro que acho que sumiu, mas olha esse link aqui por enquanto, e googla também.
Acho que a Mundo Java edição 9 tem um artigo sobre isso também…
T
thingol
Rode este programa. Ele demonstra o que ocorre se uma classe não define hashCode direito.
importjava.util.*;/** * Esta classe implementa equals e hashCode. */classCliente{privateStringnome="";privateStringendereco="";publicCliente(StringpNome,StringpEndereco){nome=pNome;endereco=pEndereco;}publicStringgetNome(){returnnome;}publicvoidsetNome(StringpNome){nome=pNome;}publicStringgetEndereco(){returnendereco;}publicvoidsetEndereco(StringpEndereco){endereco=pEndereco;}publicStringtoString(){return"nome="+nome+", endereco="+endereco;}publicbooleanequals(Objecto){if(!(oinstanceofCliente))returnfalse;if(o==this)returntrue;Clientec=(Cliente)o;// só para simplificar estou supondo que nenhum dos campos é nullreturnnome.equals(c.getNome())&&endereco.equals(c.getEndereco());}publicinthashCode(){intret=nome.hashCode();ret=ret*37+endereco.hashCode();// se houver mais campos, vá repetindo a expressão acima "ret = ret * 37 + hashCode do proximo campo"// por exemplo, ret = ret * 37 + telefone.hashCode();returnret;}}/** * Esta classe implementa equals, mas não hashCode. */classCliente2{privateStringnome="";privateStringendereco="";publicCliente2(StringpNome,StringpEndereco){nome=pNome;endereco=pEndereco;}publicStringgetNome(){returnnome;}publicvoidsetNome(StringpNome){nome=pNome;}publicStringgetEndereco(){returnendereco;}publicvoidsetEndereco(StringpEndereco){endereco=pEndereco;}publicStringtoString(){return"nome="+nome+", endereco="+endereco;}publicbooleanequals(Objecto){if(!(oinstanceofCliente2))returnfalse;if(o==this)returntrue;Cliente2c=(Cliente2)o;// só para simplificar estou supondo que nenhum dos campos é nullreturnnome.equals(c.getNome())&&endereco.equals(c.getEndereco());}}classTestHashSet{publicstaticvoidmain(String[]args){HashSet<Cliente>clientes=newHashSet<Cliente>();clientes.add(newCliente("Luis Inacio","Palacio da Alvorada"));clientes.add(newCliente("Fernandinho Beira-Mar","Presidente Bernardes"));clientes.add(newCliente("Fernandinho Beira-Mar","Presidente Bernardes"));System.out.println(clientes);// deve aparecer só uma vez o sr. FernandinhoHashSet<Cliente2>clientes2=newHashSet<Cliente2>();clientes2.add(newCliente2("Luis Inacio","Palacio da Alvorada"));clientes2.add(newCliente2("Fernandinho Beira-Mar","Presidente Bernardes"));clientes2.add(newCliente2("Fernandinho Beira-Mar","Presidente Bernardes"));System.out.println(clientes2);// O sr. Fernandinho aparece duas vezes.}}
hill
Muito obrigado rapaziada, isso resolveu o problema aqui.
Vou pesquisar + sobre esse assunto, mas o q vcs postaram fez toda a diferença.
[]´s[size=9][/size]