Set remove

11 respostas
Guilherme_Gomes

Pessoal,

Estou usando um Set (LinkedHashSet) usando generics para uma classe Domain do meu sistema, mas na hora que dou um set.remove(domain); ele não está removendo o domínio passado, alguma idéia?

Obrigado,

11 Respostas

peczenyj

Esse método retorna um boolean. Vc consegue verificar se retorna true?

Mauricio_Linhares

Você se lembrou de implementar equals() e hashCode() corretamente nessa sua classe do domínio?

Se você não tiver ambos implementados corretamente o Set não vai saber que objeto remover.

Guilherme_Gomes

A função está retornando false, sendo que posso garantir que o objeto está lá. Eu sobrescrevi o método equals da Object, mas não sobrescrevi o hasCode, precisa?

Obrigado,

Mauricio_Linhares

Tem sim, senão o HashSet não vai achar o objeto no bucket correspondente.

Guilherme_Gomes

Já o fiz, coloquei o hashCode, mas nem assim funcionou!

Estou usando lista mesmo, mas o ideal seria Set.

Mauricio_Linhares

Você implementou o hashCode() corretamente? Dois objetos que são equals tem o mesmo hashCode()?

T

De modo geral:

  • Ao usar HashSet, HashMap, LinkedHashSet, LinkedHashMap -> sobreescrever hashCode e equals da classe usada como chave
  • Ao usar TreeSet, TreeMap -> criar um Comparator para a classe usada como chave

Normalmente em meus programas acho mais útil ter as coisas em ordem crescente ou decrescente (para relatórios ou simplesmente para debugar alguma coisa) - embora seja mais lento (O(log(n)) em vez de O(1)) e gaste um pouco mais de memória, eu prefiro usar TreeSet e TreeMap.
Só uso HashSet, HashMap, LinkedHash, LinkedHashMap quando a chave é String e essa string já está normalizada para minúsculas e maiúsculas porque não tenho de definir hashCode e equals (que preguiça…)

Guilherme_Gomes

Eu fiz algo bem simples, o meu bean Domain só tem dois atributos que importam, um é integer e outro string, então coloquei:

@Override
public int hashCode() {
	return str.hashCode() + integer.hashCode();
}
Mauricio_Linhares

Péssima idéia.

A regra é que dois objetos que são equals (que o método equals retornar true) devem, obrigatoriamente, ter o mesmo hashCode(). Implemente o método hashCode() garantindo isso e você não vai ter problemas :slight_smile:

T

Normalmente, para hashcode, você pode usar a geração feita pela própria IDE (acho que o Eclipse faz isso). Essa geração é algo como:

int retorno = 0;
if (campo1 != null) retorno = campo1.hashCode();
if (campo2 != null) retorno = retorno * 37 + campo2.hashCode();
if (campo3 != null) retorno = retorno * 37 + campo3.hashCode();
...
if (campoN != null) retorno = retorno * 37 + campoN.hashCode();
return retorno;

O valor mágico 37 (um número primo) é adequado para muitas aplicações, tanto é que é usado na implementação de hashCode da classe java.lang.String.
Mas do jeito que você fez normalmente está OK.

Pode ser que seu “equals” esteja errado. Será que não está parecido com isto?

@Override public int equals (Object obj) {
    Domain dom = (Domain) obj;
    return dom.str == this.str && dom.integer == this.integer;
}
Mantu

http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf

Criado 19 de fevereiro de 2008
Ultima resposta 20 de fev. de 2008
Respostas 11
Participantes 5