Qual seria a melhor maneira para limpar um Arraylist que faz referência a outros Arraylist?
No meu caso é uma lista de Nós com suas arestas e eu preciso sempre limpar para abrir outros arquivos que variam a quantidade de Nós e arestas.
Eu imaginei algo assim:
// Na classe CNopublicvoidinicializaArestas(){listaArestas.removeAll(listaArestas);listaArestas.clear();}// Na classe CGrafopublicvoidinicializaGrafo(){CNono;while(listaNos.size()>0){no=(CNo)listaNos.remove(0);no.inicializaArestas();no=null;}listaNos=newArrayList();// poderia usar o .clear ?}
Você quer simplesmente limpar a lista? Deixar ela vazia? Use o método clear(). Isso se quiser usar o mesmo objeto, senão você instancia de novo.
lina
Oi,
listaNos=newArrayList();// poderia usar o .clear ?
Sim, neste caso você poderia usar o clear.
Tchauzin!
T
tamanini
ok, obrigado pela ajuda pessoal.
No meu caso, eu irei fazer um novo grafo, que será gerado através de um outro arquivo texto. Então como boa prática de programação, irei remover e limpar as arestas e os nós para que o gc remova os objetos e ao abrir o arquivo que contém um novo grafo, vou instânciando novos nós e arestas em outro método:
// Na classe CNo publicvoidinicializaArestas(){listaArestas.removeAll(listaArestas);// remove todas as arestas do nólistaArestas.clear();// limpa as arestas para que o gc remova os objetos}// Na classe CGrafo publicvoidinicializaGrafo(){CNono=null;// inicializa a referência como nulowhile(listaNos.size()>0){// verifica se contém objetosno=(CNo)listaNos.remove(0);// passa a referência antes de remover o objetono.inicializaArestas();// remove todas as arestas do nó e instância novamenteno=null;// deixa preparado para gc limpar }listaNos.clear();// limpa a lista de nós para o gc}
É isso?
ViniGodoy
Se você vai dar o clear, não precisa dar o removeAll… e vice versa!
T
tamanini
Valeu Vini.
Então só o .removeAll() seria o suficiente na classe CNo, assim como eu removendo os Nós pelo .remove, não é necessário o .clear no final da classe CGrafo, correto?
E os comentários que fiz estão corretos?
T
tamanini
Só mais essa dúvida pessoal! Alguém?
Andre_Brito
tamanini:
Valeu Vini.
Então só o .removeAll() seria o suficiente na classe CNo, assim como eu removendo os Nós pelo .remove, não é necessário o .clear no final da classe CGrafo, correto?
E os comentários que fiz estão corretos?
O .clear não é necessário. Foi o que o ViniGodoy falou…
Sobre os comentários, só na linha 13: vai remover todas as arestas e instanciar novamente? Não vai só remover todas as arestas?
T
tamanini
Andre Brito:
O .clear não é necessário. Foi o que o ViniGodoy falou…
Sobre os comentários, só na linha 13: vai remover todas as arestas e instanciar novamente? Não vai só remover todas as arestas?
Erro meu, é que antes eu estava pensando colocar no método um new Arraylist(), logo depois que eu removesse as arestas.
Mas já corrigi, obrigado.
ViniGodoy
Também seria desnecessário fazer no = null naquela situação. A variável no é local, logo, ela será automaticamente deletada assim que a função sair. De qualquer modo, cada novo no atribuido irá sobrescrever a referência anterior, e tornar o no também passível de deleção.
Acho que você está meio obsecado pelo garbage collector… hehehheheh
É bom se perguntar sempre se é necessário nulificar variáveis. Essa prática é mais do que louvável e deveria ser feito por todos.
Entretanto, se as reposta for não, não coloque código extra redundante “só para garantir”.
Seu código mesmo fica resumido a:
publicvoidinicializaArestas(){listaArestas.clear();// limpa as arestas para que o gc remova os objetos }// Na classe CGrafo publicvoidinicializaGrafo(){listaNos.clear();// limpa a lista de nós para o gc }
ViniGodoy
Outra coisa. Sua variável CNo só é usada dentro do while.
Portanto, não a crie fora do while. Isso aumenta o escopo da variável desnecessariamente, e não melhora a performance do seu código.
Embora aquele while seja descenessário, se for fazer um while com variáveis locais, faça assim:
while(listaNos.size()>0){//verificasecontémobjetosCNono=(CNo)listaNos.remove(0); // passa a referência antes de remover o objeto no.inicializaArestas(); // remove todas as arestas do nó e instância novamente }
Outra coisa.
Por que a sua listaNos não usa os generics? Use-os e evite aquele cast!
Cast são operações extremamente inseguras. Com a lista declarada usando generics, o mesmo while poderia ficar assim:
while (listaNos.size() > 0) { // verifica se contém objetos
listaNos.remove(0).inicializaArestar(); // passa a referência antes de remover o objeto
}
É claro que não há muito sentido em inicializar arestar de um nó que será excluído, como bem falou o colega. Por isso só o clear já seria suficiente.
T
tamanini
Acho que você está meio obsecado pelo garbage collector... hehehheheh
hahaha...
Para quem está saindo de VB6. E via sua memória só aumentando e nunca diminuindo quando fechava um form.
Eu imaginava que era necessário atribuir null a no, para passar uma nova referência e tb o receio do garbage collector de não coletar.
Mas obrigado pelas dicas. Vou acabar usando mesmo generics. É que estou mais acostumado a trabalhar com ArrayList sem generics e como tenho que entregar esse trabalho semana que vem, nem pensei em generics.
O meu código resumido sem generics ficará na verdade assim, correto?:
// Na classe CNopublicvoidinicializaArestas(){listaArestas.clear();// limpa as arestas para que o gc remova os objetos }// Na classe CGrafo publicvoidinicializaGrafo(){listaNos.inicializaArestas();// método para limpar as arestas de nólistaNos.clear();// limpa a lista de nós para o gc }
e com generics, poderia fazer assim?:
// Na classe CNopublicvoidinicializaArestas(){listaArestas.clear();// limpa as arestas para que o gc remova os objetos }// Na classe CGrafo publicvoidinicializaGrafo(){listaNos.clear().inicializaArestas();// limpa a lista de arestas e nós para o gc }
ViniGodoy
Ainda não entendi… Por que vc quer chamar inicializa arestas se os nós serão destruídos?
PS: Faz bem em sair do VB6, uma linguagem com o comando “On error resume next” não pode ser levada a sério.
T
tamanini
Bem, pelo que eu entendo, se eu destruir apenas os nós, as arestas continuarão apontando para seus objetos. E com isso o gc(eu de novo com o garbage collector. rsrs) não irá coletar.
ViniGodoy
Mas haverá mais alguém apontando para as arestas?
Se o nó for coletado, as arestas ficarão sem ninguém apontando para elas. E então serão coletadas. Os objetos apontados por elas imediatamente ficarão sem ninguém apontando para eles… e serão coletados. E por aí vai, até que tudo o que só tinha como vínculo o nó seja coletado.
T
tamanini
Bem, é que eu entendo que os objetos nós seriam coletados, mas os objetos arestas não seriam, pois a listaAresta continuam apontando para eles, não é isso?
Obs.: Na especificação do trabalho, existem os métodos inicializaGrafo() e inicializaArestas(), então eu entendo que devo limpar a minha listaArestas da classe CNo e minha listaNos da classe CGrafo.
No meu caso, existe as seguintes classes:
CGrafo -> CNo -> CAresta
ViniGodoy
Sim, mas a partir do momento que vc limpa todos os nós (com o clear), as arestas vão no embalo.
A menos que haja ainda outra classe referenciando arestas, que não os nós.
T
tamanini
Bem, mas então qual seriam o motivo de ter na especificação o método inicializaAresta()? Eu vou até tirar essa dúvida com um dos professores.
Eu estou sem o meu código aqui, mas a forma que eu fiz com generics é para funcionar tb, correto?
ViniGodoy
Acho que funciona também.
Então, essa pergunta que vc por último era mais ou menos a pergunta que eu estava me fazendo…