[RESOLVIDO] Duvida em ArrayList

7 respostas
VandersonAssis

Uma coisa muito estranha aconteceu aqui. Seguinte … tenho o seguinte código o que ele faz é popular um objeto contato e depois o adiciona na ArrayList. O estranho é que só funciona corretamente quando instancio o ContatoController dentro do while, se eu instancia-lo fora do while ele adiciona o contato na lista, porém ele replica o ultimo contato em toda a lista. Exemplo: Se eu tiver uma lista de 16 contatos ele coloca o ultimo contato nas 16 posições. Já quando instancio o contato dentro do while funciona corretamente. Por que isso acontece?

while(rs.next() == true){
				ContatoController contato = new ContatoController();
				contato.setId(rs.getInt("id"));
				contato.setNome(rs.getString("nome"));
				contato.setIdade(rs.getInt("idade"));
				contato.setSexo(rs.getString("sexo"));				
				lista.add(contato);
}

7 Respostas

G

mas o q há de estranho?

é exatamente o q vc estaria mandando fazer.

vc estanciou um e add o mesmo varias vezes.

VandersonAssis

GilsonNunes:
mas o q há de estranho?

é exatamente o q vc estaria mandando fazer.

vc estanciou um e add o mesmo varias vezes.

Sim eu sei que instanciei um. Mas já que dentro do laço eu estava a cada volta atualizando seus atributos, não deveria adicionar o contato com os atributos atualizados? E se eu dei um add com um valor, por que no proximo add ele altera o valor anterior? Porque pelo que eu sei o add adiciona um valor apenas no final da lista, não se importando com o que já foi adicionado. Entendes minha dúvida.

caio.ribeiro.pereira

O código esta correto, e é uma boa prática instanciar desse jeito o ContatoController, pois você trabalha num escopo fechado em que este objeto apenas nasce para carregar os seus atributos até ser enviado para o ArrayList e morre quando surge uma nova instância ou quando o loop while finaliza.

Se você usar apenas uma única instância de ContatoController que no seu caso você gostaria dele fora do while, vai sujar o seu ArrayList pois haverá apenas uma única referência de um mesmo objeto dentro do ArrayList, isso porque o próprio ArrayList utiliza a mesma referência do objeto na memória, ou seja, quando se faz novas instâncias é colocado no array novos objetos.

Tem um nome correto para esse conceito que acabei de dizer, porém eu não lembro rs se alguém souber ficarei grato!

Bruno_Cunha

Não há nada estranho no comportamento do programa.

Deixa eu tentar facilitar um pouco…

Quando você criava o ContatoController antes do while, somente uma instância era criada.
Isso quer dizer que, mesmo você adicionando ele em uma lista, você possui “controle” sobre esse objeto (a referência dele).

O que você estava fazendo era adicionando a mesma instancia de ContatoController na lista para cada registro do seu ResultSet (rs.next())
Ou seja, quando você iria alterar o valor do último registro, tudo o que foi adicionado na sua lista era alterado também - pois eram o MESMO objeto.

Agora dessa forma está correto!

Espero ter ajudado.

G

kira911:
GilsonNunes:
mas o q há de estranho?

é exatamente o q vc estaria mandando fazer.

vc estanciou um e add o mesmo varias vezes.

Sim eu sei que instanciei um. Mas já que dentro do laço eu estava a cada volta atualizando seus atributos, não deveria adicionar o contato com os atributos atualizados? E se eu dei um add com um valor, por que no proximo add ele altera o valor anterior? Porque pelo que eu sei o add adiciona um valor apenas no final da lista, não se importando com o que já foi adicionado. Entendes minha dúvida.

é pq vc ta achando q qdo add na lista tá adicionando uma cópia. e não é. só add uma referencia.

turim

Olá kira911,

Quando você instância Contato fora do while, você está criando uma única instância, setando os valores e adicionando no ArrayList.

O que acontece é que por ser um único objeto, acaba que irá prevalecer os últimos valores setados, e o ArrayList aceita instâncias repetidas, ou seja, você tem uma instância de Contato, em várias posições de um ArrayList.

Só mais uma dica, nunca esqueça de invocar o método close(), ao final do while do ResultSet, assim você evita “vazamentos” de memória.

Espero que lhe ajude, valeu.

VandersonAssis

Esqueci que as variaveis tem referencias para objetos e não o proprio objeto. Que mancada. Muito obrigado pessoal!!

Criado 2 de março de 2012
Ultima resposta 4 de mar. de 2012
Respostas 7
Participantes 5