Problema com HashSet

3 respostas
danielbchaves

Estava tentando ajudar um cara em um post e vim fazer um exemplo para ficar mais fácil, porém o exemplo não deu certo hehe

Eu criei um HashSet para adicionar um objeto meu que possui o equals implementado
Adiciono 2 objetos iguais no HashSet, o equals deles retornou true, mas quando mando exibir todos os itens da coleção aparecem os dois. Na segunda linha da saída mostra o resultado do equals, depois aparecem os 2 elementos da coleção, deveria ser só um

public static void main(String[] args)
	{
		HashSet<String> strings = new HashSet<String>();
		
		strings.add("texto");
		strings.add("texto");
		for (Iterator i = strings.iterator(); i.hasNext();) {
			String sss = (String) i.next();
			System.out.println(sss);
		}
		
		HashSet<Vertice> vertices = new HashSet<Vertice>();
		Vertice v1 = new Vertice("Rio de Janeiro", 10);
		Vertice v2 = new Vertice("Rio de Janeiro", 10);
		System.out.println(v1.equals(v2));
		vertices.add(v1);
		vertices.add(v2);
		
		for (Iterator i = vertices.iterator(); i.hasNext();) {
			Vertice v = (Vertice) i.next();
			System.out.println(v);
		}
	}
}

A saída desse programa foi essa

texto true Rio de Janeiro - 10 Rio de Janeiro - 10

Não entendi, para mim ele usava o método equals para saber se o elemento já existe, o equals retornou true mas mesmo assim ele adicionou repetido. Alguém sabe dizer o porquê?

se alguém quiser colocar pra rodar aí vai o código da classe Vertice

public class Vertice
{
	private String cidade = null;
	private int hora = 0;
	
	public Vertice( String c, int h )
	{
		cidade = c;
		hora = h;
	}
	
	@Override
	public boolean equals(Object o)
	{
		if (o != null && o instanceof Vertice)
		{
			Vertice v = (Vertice) o;
			if( ( ( v.cidade != null && this.cidade != null ) && 
			      ( v.cidade.equals(this.cidade) ) )
			    || ( v.cidade == null && this.cidade == null )
			  )
			{
				if( v.hora == this.hora )
					return true;
			}
		}
		return false;
	}
	
	@Override
	public String toString()
	{
		return cidade + " - " + hora;
	}
}

3 Respostas

Alkamavo

resolvido…

o segredo estava no equals, o hashSet para ver se o objecto esta repetido usa o equals(Object xpto) tempos de redefinir este metodo na classe que criamos para o nosso objecto mas com o parametro Objec, na comparação fazemos uma cast para o tipo do nosso objecto e kuando ele usar (HashSet) usa como deve ser…

aqui esta:

public boolean equals(Object o) { if (this.cidade.equals(((Vertice) o).getcidade()) && this.hora == ((Vertice) o).gethora()) { return true; } else return false; }

danielbchaves

deu certo aqui, pelo que pude ver para funcionar o HashSet certinho, precisei sobrescrever o equals e o hashCode, se não fizesse qualquer um dos dois não funcionava corretamente

moikawa

Você vai ter que implementar na classe Vertice uma sobrecarga do método hashCode().
O HashSet funciona assim, ele verifica se dois objetos são iguais se eles tem hashCode iguais, no caso da sua classe Vertice ta usando o hashCode do Object. Tenta sobrescrever o hashCode na sua classe Vertice de uma maneira que cada objeto tenha um hashCode unico, sei la, pode ser

@Override
public int hashCode()
{
         return (cidade + Integer.toString( hora ) ).hashCode();
}

Vê ai se da certo.

Boa sorte

Criado 28 de junho de 2008
Ultima resposta 28 de jun. de 2008
Respostas 3
Participantes 3