Limpar ArrayList?

Olá pessoal.

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:

[code]// Na classe CNo
public void inicializaArestas() {
listaArestas.removeAll(listaArestas);
listaArestas.clear();
}

// Na classe CGrafo
public void inicializaGrafo() {
CNo no;

while (listaNos.size() > 0) {
	no = (CNo) listaNos.remove(0);
	no.inicializaArestas(); 
	no = null;
}
listaNos = new ArrayList();       // poderia usar o .clear ?

}[/code]

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.

Oi,

listaNos = new ArrayList();       // poderia usar o .clear ?

Sim, neste caso você poderia usar o clear.

Tchauzin!

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:

[code]// Na classe CNo
public void inicializaArestas() {
listaArestas.removeAll(listaArestas); // remove todas as arestas do nó
listaArestas.clear(); // limpa as arestas para que o gc remova os objetos
}

// Na classe CGrafo
public void inicializaGrafo() {
CNo no = null; // inicializa a referência como nulo

 while (listaNos.size() > 0) {            // verifica se contém objetos
     no = (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
     no = null;                                 // deixa preparado para gc limpar 
 }  
 listaNos.clear();   // limpa a lista de nós para o gc

} [/code]

É isso?

Se você vai dar o clear, não precisa dar o removeAll… e vice versa!

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?

Só mais essa dúvida pessoal! Alguém?

[quote=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?

[/quote]

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?

[quote=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?[/quote]

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.

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:

public void inicializaArestas() {     
     listaArestas.clear();                         // limpa as arestas para que o gc remova os objetos   
}     
  
// Na classe CGrafo     
public void inicializaGrafo() {            
     listaNos.clear();   // limpa a lista de nós para o gc   
}

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) {            // verifica se contém objetos   
         CNo no = (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. :slight_smile:

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?:

[code]// Na classe CNo
public void inicializaArestas() {
listaArestas.clear(); // limpa as arestas para que o gc remova os objetos
}

// Na classe CGrafo
public void inicializaGrafo() {
listaNos.inicializaArestas(); // método para limpar as arestas de nó
listaNos.clear(); // limpa a lista de nós para o gc
}[/code]

e com generics, poderia fazer assim?:

[code]// Na classe CNo
public void inicializaArestas() {
listaArestas.clear(); // limpa as arestas para que o gc remova os objetos
}

// Na classe CGrafo
public void inicializaGrafo() {
listaNos.clear().inicializaArestas(); // limpa a lista de arestas e nós para o gc
}[/code]

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.

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.

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.

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

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.

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?

Acho que funciona também.
Então, essa pergunta que vc por último era mais ou menos a pergunta que eu estava me fazendo…