Problema com ArrayList e HashSet[RESOLVIDO]

18 respostas
renato_ramos

Oi!

tava dando uma olhada pro ai na internet e achei esse exemplo

public class ConvertListToSet {

    public void convertFromListToSet() {

    List fruitsList = new ArrayList ();
        fruitsList.add("Apples");
        fruitsList.add("Bananas");
        fruitsList.add("Oranges");
        fruitsList.add("Grapes");

        Set fruitsSet = new HashSet(fruitsList);

        for (Object theFruit : fruitsSet)
         System.out.println(theFruit);

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new ConvertoListToSet().convertFromListToSet();
    }
}

e funcinou... mas adaptando para minha aplicação

List<Alternativa> alternativaList = new ArrayList<Alternativa>();
            if (index > 0) {
                for (int i = 0; i < index; i++) {
                    Alternativa alternativa = (Alternativa) listModelAlternativa.getElementAt(i);
                   // alternativa.setIdQuestao(questao);
                    alternativaList.add(alternativa);
                }
        Set<Alternativa> alternativaSet = new HashSet<Alternativa>(alternativaList);

e quando eu vou ver o set de alternativa só tem um elemento..

gostaria de saber porque =/

mt obrigado

18 Respostas

P

sua variavel index ta recebendo algum valor?

troca ela por isso

for (int i = 0; i < alternativaList.size(); i++)
E

Para usar um HashSet, você precisa redefinir o método public int hashCode() dessa classe SuaClasse.

renato_ramos

PedroGuerra:
sua variavel index ta recebendo algum valor?

troca ela por isso

for (int i = 0; i < alternativaList.size(); i++)

pega sim

int index = listModelAlternativa.getSize();

esqueci de colocar ali… mals ae

entanglement… não sabia dessa… voce tem um exemplo de como eu posso fazer isso

valeu!

ViniGodoy

Esse exemplo é melhor:
http://www.guj.com.br/posts/list/74068.java#389435

renato_ramos

obrigado vini

ms tem um exemplo de como transformar uma List pra um HashSet

como eu criei a classe usando o wizarddo netbeans pra criar classes a partir de um bd

ele faz esse metodo de “fabrica”

@Override
    public int hashCode() {
        int hash = 0;
        hash += (idAlternativa != null ? idAlternativa.hashCode() : 0);
        return hash;
    }

mas acho que nun tah funcionando neh?

valeu!

E

Você está usando o Eclipse ou o NetBeans? Ele tem uma opção de gerar o método hashCode para você.

No NetBeans, clique com o botão direito sobre o nome da classe (naquela linha onde você definiu “public class Alternativa”), e então escolha a opção “Inserir Código…”, e então escolha a opção “equals() e hashCode()…”.
Escolha os campos da classe que você precisa usar como chaves (por exemplo, em um campo “cliente” você normalmente usaria apenas o campo “código”), e então clique em “Gerar”.

No Eclipse, existe algo parecido. Vou ver como é que é.

renato_ramos

acho que eu descobri oq ta acontecendo… eu não to settando o id da classe, porque eu to settando o set em um atributo set de outra classe pra gravar no banco usando hibernate… ele gera os id sozinho ‘-’

com list ele ia que ia… mas tive que mudar pra set =/

como eu posso resolver isso?

renamed

È realmente necessário implementar esse método hash? eu lembro q na primeira cadeira de java na facul meu professor nos obrigou a usar Hash e eu nao lembro de ter feito isso nao…

E

A definição default do método hashCode pode ser útil se você quiser usar um HashSet em que dois objetos que contém os mesmos valores, mas são objetos distintos, devem ser considerados diferentes.

Você precisa redefinir hashCode se você quer que dois objetos que contém alguns valores iguais (como se fossem chaves compostas em uma tabela SQL) devam ser considerados o mesmo objeto.

ViniGodoy

Sim:

Set<Classe> set = new HashSet<Classe>(suaLista);

Só cuidado que elementos com o mesmo hashcode serão descartados.

ViniGodoy

Para usar as coleções baseadas em hash (HashSet, LinkedHashSet, HashMap), sim.

Para mais informações sobre como implementar o hashcode, leiam:
http://www.guj.com.br/posts/list/52485.java#276120

Também fiz uma classezinha prática para implementar esse algoritmo:
http://www.guj.com.br/posts/list/101275.java#546125

Fica menos rebuscado que o código que as IDEs geram.

ViniGodoy

Uma alternativa ao HashSet, se sua classe for ordenável, é usar o TreeSet. Nesse caso, ou sua classe deve implementar Comparable, ou você deve fornecer um Comparator.

Set<Classe> seuSet = new TreeSet<Classe>(suaLista);

As vezes, é mais fácil implementar isso do que o hashcode. Para saber mais sobre comparator e comparable, leia:
http://www.guj.com.br/posts/list/45985.java

E

Para 95% dos usos costumeiros, é melhor usar um TreeSet, não um HashSet.

Isso é porque é bem parecido com o uso que você faria em um banco de dados com uma chave primária - você não pode inserir 2 registros com a mesma chave, e quando você efetua uma consulta, os registros já vêm na ordem dada pela chave primária.

renato_ramos

Vini usando sua classe tah dando java.lang.StackOverflowError

eu nao posso usar a classe Random pra gerar?

ViniGodoy

renato_ramos:
Vini usando sua classe tah dando java.lang.StackOverflowError
eu nao posso usar a classe Random pra gerar?

Não, objetos iguais precisam ter hashcodes iguais. Enquanto um objeto permanecer inalterado, seu hashcode não pode mudar.
Como você está usando a classe???

renato_ramos
@Override
    public int hashCode() {
         return new HashBuilder(this).hashCode();
    }

assim ^^’

vou explicar o que eu to fazendo…

eu tenho duas classes de persistencia… com relacionamento A 1-n B

a classe A tem um Set da classe B… to usando o set pq nun tava conseguindo subir com mode Eager com list ‘-’

ai qndo eu coloquei o set e fui testar o cadastro denovo… só tava pegando um valor da lista ‘-’

eu qru settar o set e gravar igual eu estava fazendo com o ArrayList… pq com o array eu só settava a descrição da classe b… sem id… e gravava de boa…

bom é isso o problema todo …

mt obrigado pela atenção de vc’s

ViniGodoy

Mas assim você não pode usar… :lol:

O hashBuilder precisa saber que campos da sua classe serão usados para gerar o hash. Se você passar um objeto para ele, ele tentará chamar o método hashCode() desse objeto.

Por exemplo, se os campos relevantes da sua classe são id e nome, faça:

@Override public int hashCode() { return new HashBuilder(id).add(nome).hashCode(); }

Se for uma alternativa de uma questão, talvez seja assim:

@Override public int hashCode() { return new HashBuilder(questao).add(idAlternativa).hashCode(); }

renato_ramos

aeeee

@Override public int hashCode() { return new HashBuilder().add(this.descAlternativa).hashCode(); }

resolvido…

omg!

coisa complicada…

muito obrigado messssmo!

Criado 26 de novembro de 2009
Ultima resposta 26 de nov. de 2009
Respostas 18
Participantes 5