Pessoal tudo bem…
Pessoal quando eu vou usar esses conjuntos eu preciso implementar os metodos da classe Object como o equals() e hashCode() para mim ter uma melhor performace ou não ? Por favor se a resposta for sim me da um exemplo.
Agradeço desde Já
HashSet e LinkedHashSet
14 Respostas
Não é “melhor performance”.
Simplesmente é “para funcionar direito”.
Senão você pode ter problemas com elementos repetidos em um hashset, ou então de não conseguir encontrar mais um elemento.
Para implementar equals, basta comparar os atributos relevantes em sua classe. (Quais são os atributos relevantes? Você deve saber melhor que eu; são aqueles que importam ou que não são obtidos a partir de outros apenas por um cálculo).
Para implementar hashCode, normalmente você pega os hashCodes de cada atributo relevante e os combina usando uma conta como a seguinte (que é parecida com o cálculo do hashcode de uma String):
class Aluno {
private String nome;
private String endereco;
private int idade;
private transient int comprimentoDoNome; // este atributo é irrelevante pois pode ser obtido a partir do atributo "nome"
private transient boolean menorDeIdade; // é irrelevante porque pode ser obtido a partir do atributo "idade".
public int hashCode () {
int ret;
ret = nome.hashCode();
ret = ret * 37 + endereco.hashCode();
ret = ret * 37 + idade;
return ret;
}
public boolean equals (Object obj) {
if (! (obj instanceof Aluno && obj.getClass() == Aluno.class) ) return false;
if (obj == this) return true;
Aluno outro = (Aluno) obj;
return this.nome.equals(outro.nome) && this.endereco.equals(outro.endereco) && this.idade == outro.idade;
}
// seguem-se os getters & setters.
}
Sim, vc deve implementar equals e hashcode corretamente para ter uma melhor performance.
Lembre-se que existem várias formas de implementar hashcode. Algumas são mais eficiente que outras.
Procure por HashMap e colisão de hash para mais informação.
Pessoal agora eu to com outra dúvida que é a seguinte qual a diferença entre HashSet e HashMap ???
HashSet não permite elementos duplos ( mas o que ele considera como elementos duplos…)
HashMap não permite Key duplas … eu tô me confundindo com essas caras… 
Set = Conjunto (uma coleção de valores únicos).
Map = Mapa (ou seja, algo que associa uma chave única com um valor).
Por exemplo: você pode ter um Set de alunos, ou então um Map que associa nomes a alunos.
(Curiosidade: no Java os Sets são implementados como Maps, mas com a chave igual ao valor. Mas isso é só para evitar duplicar código).
Pessoal agora eu to com outra dúvida que é a seguinte qual a diferença entre HashSet e HashMap ???
HashSet não permite elementos duplos ( mas o que ele considera como elementos duplos…)
O HashSet em particular considera iguais elementos tal que a.equals(b) seja true*. O elemento é duplicado quando ele é igual a um que já está no conjunto. O TreeSet , um outro tipo de Set, usa um Comparator para avaliar se os objetos são iguais.
- na realidade ele avalia primeiro os hashsodes e depois, se houver colisão, o equals. Já que o hash ser diferente indica que os objetos são diferentes, mas ser igual não indica que são iguais.
thingol eu continuei sem entender cara você poderia dar um exemplo de cada um por favor [/url]?
Vamos lá. Só para simplificar não vou usar setters & getters:
class Pessoa {
public String nome; public String endereco;
public int hashCode () { return nome.hashCode() * 37 + endereco.hashCode(); }
public boolean equals(Object obj) {
if (! (obj instanceof Pessoa && obj.getClass() == Pessoa.class) ) return false;
if (obj == this) return true;
Pessoa outro = (Pessoa) obj;
return this.nome.equals(outro.nome) && this.endereco.equals(outro.endereco);
}
public Pessoa (String pNome, String pEndereco) { nome = pNome; endereco = pEndereco; }
public String toString() { return "(nome=" + nome + ", endereco=" + endereco + ")"; }
}
...
// Uso de "set"
Set<Pessoa> pessoas = new HashSet<Pessoa>();
pessoas.add (new Pessoa ("José Arimatéia", "Rua do Calvário, 200"));
pessoas.add (new Pessoa ("Judas Iscariotes", "Terreno do Aceldama, 13"));
System.out.println (pessoas);
// Uso de "map"
Map<String,Pessoa> pessoasPorApelido = new HashMap<String,Pessoa>();
pessoasPorApelido.put ("Zeca", new Pessoa ("José do Pagode", "Morro da Catimba"));
pessoasPorApelido.put ("Dani", new Pessoa ("Daniela do Ronaldinho", "Rua dos Pelados"));
// -> vamos procurar a Dani em "pessoasPorApelido"
System.out.println (pessoasPorApelido.get ("Dani"));
Pessoal agora eu to com outra dúvida que é a seguinte qual a diferença entre HashSet e HashMap ???
HashSet não permite elementos duplos ( mas o que ele considera como elementos duplos…)
HashMap não permite Key duplas … eu tô me confundindo com essas caras… :D
Bom dar para confudir mesmo. mas vamos la um HashSet é apenas para nao aceitar elementos duplicado… no sua coleção… entao vc quer garantir que se alguem tentar adicionar um objeto que ja exista no seu conjunto ele nao adiciona… claro para ele saber se igual… o seu metodo equals deve dizer isso e de uma maneria mais eficiente seu hashcode deve ser implementado tb de forma eficiente.
o HashMap - usa chave e o valor… imagine agora… vc quando compra uma tv por exemplo o que tem na plaquionha? o codigo do protuto (que interessa ao vendedor normalmente) e o nome do produto relacionado com o codigo, nao pode ter dois codigos de produtos iguais… de forma nenhuma. ja imaginou o problema ne? Então por isso XXXMap nao permite keys repetidos.
......
Map<Integer,String> cadprod = new HashMap<Integer,String>();
cadprod.put(1020,"Tv plasma");
cadprod.put(1021, "DVD");
cad.prod.put(1020, "Tv LCD");
...
nesse pequeno trecho de codigo… vc percebe a essencia do Map tenho uma chave do tipo Integer e o valor do tipo String associado a essa chave… entao quando adiciono no final 1020 ele apenas atualiza o valor daquela chave… agora se vc mandar imprimir o valor da chave 1020 vai imprimir “TV LCD” e nao o primeiro… se usar Set ele retorna false. e pronto nesse caso de Map o valor do key é atualizado.
Set != Map, as vezes confude no inicio pq as duas interface tem a class TreeMap.
Mas pratique até entender… faça pequenos programas… mas que seja funciona com essas classes e as outras tb.
espero ter ajudado flw!!
qualquer coisa so gritar…
PEssoal eu fiz um classe chamada Aluno com o metodo equals().. para testar os LinkedHashSet e HashSet .. Mas não está funcionando alguem pode me mostrar por que .. O código é o seguinte....
class Aluno{
String nome;
public Aluno(String nome){
this.nome = nome;
}
@Override
public boolean equals(Object arg0) {
if((arg0 instanceof Aluno) && ((Aluno)arg0).nome.equals(this.nome))
return true;
else
return false;
}
public String toString(){
return this.nome;
}
}
Depois disso eu faço um LinkedHashSet...
public static void main(String ... rafa){
Set<Aluno> conjunto = new LinkedHashSet<Aluno>();
conjunto.add(new Aluno("Rafael"));
conjunto.add(new Aluno("Rafael"));
conjunto.add(new Aluno("Patricia"));
conjunto.add(new Aluno("Fernando"));
for(Aluno alunos : conjunto)
System.out.println(alunos);//ACONTECE QUE OS NOMES RAFAEL ENTRARAM DUAS VEZES.....
}
Você tem de implementar em conjunto sempre o equals e o hashCode. Sempre.
Thingol sempre que eu usar Classes da interface Set e Map eu tenho que implementar hashCode() method e o equals() method ou só quando usar Set ?
observe o nome da class XXXHashSet… entao para ter uma iteração eficiente precisa implementar o hashCode().

Para usar como o valor de um HashSet ou LinkedHashSet, ou como a chave de um HashSet ou LinkedHashSet, você precisa definir equals e hashCode.
Para usar como o valor de um TreeSet ou como a chave de um TreeMap, você precisa implementar Comparable.
Agora uma pergunta: A multiplicação no método do hashCode, não deve ser 37, por via de regra, correto?
public class Aluno {
private String nome;
public Aluno(String nome) {
this.nome = nome;
}
public String getNome() {
return this.nome;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Aluno && (obj.getClass().equals(Aluno.class))) {
if (((Aluno) obj).getNome().equals(getNome())) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
int hashCode = this.nome.hashCode() * 37;
return hashCode;
}
}
import java.util.LinkedHashSet;
import java.util.Set;
public class Principal_LinkedHashSet {
public static void main(String[] args) {
Set<Aluno> alunos = new LinkedHashSet<Aluno>();
alunos.add(new Aluno("Rafael"));
alunos.add(new Aluno("Rafael"));
alunos.add(new Aluno("Patricia"));
alunos.add(new Aluno("Bernardo"));
for (Aluno aluno : alunos) {
System.out.println(aluno.getNome());
}
}
}