Problemas com método recursivo

Pessoal, nunca usei funções recursivas além do que vi na faculdade, porém estou com uma situação onde resolvi usar e estou me deparando com um problema, após executar a recursão até o ponto de saída, o programa volta a executar a função, parece que fica na pilha. A situação é a seguinte, tenho um objeto com 2 atributos, o nome do produto e o valor, e o meu programa recebe uma lista de objetos desse tipo, quando o valor do patrimônio for 0, quero excluí-lo.

Utilizando uma iteração normal, quando eu fazia o if para descobrir se aquela instância do objeto tinha o valor 0, eu excluia a mesma da lista, porém depois ao devolver a lista para o método chamador recebia uma mensagem do tipo ?The collection was modified, etc…? , alguma coisa assim.

Então fiz uma aplicação standalone para isolar o teste, segue abaixo, com os comentários do ponto onde o método volta a ser executado. Sei que existem outras maneiras de resolver esse problema até mesmo de maneira mais elegante mas eu gostaria de usar recursão até para fins de estudo. Grato.


public class Resumo
{
        
    private String produto;
    private double patrimonio;
        
    public Resumo(String produto, double patrimonio)
    {
        this.produto = produto;
        this.patrimonio = patrimonio;
    
    }

    public String getProduto() {
        return produto;
    }

    public void setProduto(String produto) {
        this.produto = produto;
    }

    public double getPatrimonio() {
        return patrimonio;
    }

    public void setPatrimonio(double patrimonio) {
        this.patrimonio = patrimonio;
    }

}

import java.util.*;

public class Recursive 
{

    public static void main(String args[])
    {
        
        List<Resumo> res = new ArrayList<Resumo>();
                    
        res.add(new Resumo("Fundos", 1000));
        res.add(new Resumo("Renda Fixa", 0));
        res.add(new Resumo("Renda var", 0));
        
        Teste(res);
    }
    
    static void Teste(List<Resumo> res)
    {
        
        for (Resumo obj : res)
        {
           if (obj.getPatrimonio() == 0)
           {
               res.remove(obj);
               Teste(res);
           }
        }
       
        Exibe(res);
    
    }
    
    static void Exibe(List<Resumo> res)
    {
        try
        {
            for (Resumo obj : res)
            {
                System.out.println(obj.getProduto());
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    
    }

    
}

Poderiam me dar um help? Obrigado.

Ola,

O teu problema é o ConcurrentModificationException, que ocorre pq vc tá interando emcima de uma coleção, e tenta modificar…

A forma como vc fez tb vai te gerar este problema, vc tem duas soluções,
1-> Vc pode fazer isto usando o “for” antigo.

for(int i=0;i<res.size();i++){ Resumo resumo = res.get(i); if(resumo.getPatrimonio() == 0){ res.remove(i); i--; continue; } }

2->Criar uma nova coleção e armazenar nela os objetos a serem removidos, e depois removelos da coleção principal:

List<Resumo> aExcluir = new ArrayList<Resumo>(); for(Resumo resumo : res){ if(resumo.getPatrimonio() == 0){ aExcluir.add(resumo); } } res.removeAll(aExcluir);

Você pode também usar o método remove do Iterator. Apesar do padrão Iterator não precisar suportar opção de remoção, a implementação do java.util.Iterator suporta. Então, seria algo assim:

static void Teste(List<Resumo> res) {

        Iterator<Resumo> iterator = res.iterator();
        while ( iterator.hasNext() ) {
            Resumo obj = iterator.next();
            if ( obj.getPatrimonio() == 0 ) {
                iterator.remove();
                Teste(res);
            }
        }

        Exibe(res);

    }

Falou!

Não entendi o pq da recusividade… o pq de vc dentro de um for… chamar o mesmo método… que vai voltar para o inicio do for … o.O

static void Teste(List<Resumo> resumos) { Iterator<Resumo> resumo = resumos.iterator(); while ( resumo.hasNext() ) if ( resumo.next().getPatrimonio() == 0 ) resumo.remove(); Exibe(resumos); }

[quote=Lavieri]Não entendi o pq da recusividade… o pq de vc dentro de um for… chamar o mesmo método… que vai voltar para o inicio do for … o.O

static void Teste(List<Resumo> resumos) { Iterator<Resumo> resumo = resumos.iterator(); while ( resumo.hasNext() ) if ( resumo.next().getPatrimonio() == 0 ) resumo.remove(); Exibe(resumos); }
[/quote]

[quote=Daniel_MV]
"Sei que existem outras maneiras de resolver esse problema até mesmo de maneira mais elegante mas eu gostaria de usar recursão até para fins de estudo. Grato. "

[/quote][/quote]

sim sim, deve ter varias outras formas de fazer, mais eu realmente não entendi o pq da recursividade nem como faze-la neste caso, principalmente por ter uma recursividade dentro de um for… o.O … não foi um critica e sim um não entendimento, ate pq vc na sua duvida, pediu que alguem te ajuda-se a solucionar com recursividade, e eu não achei como =/

Ola,

Ajudando um pouco mais…

Como resolver com recursividade… :

public void teste(List<Resumo> res, int index){
  if(res.size() <= index || index <0){
    return;
  }
  Resumo resumo = res.get(index);
  if(resumo.getPatrimonio() == 0){
    res.remove(resumo);
    teste(res, index);
  }else{
    index++;
    teste(res, index);
  }
}

//invocando

 public static void main(String args[])    {             
         List<Resumo> res = new ArrayList<Resumo>();                         
         res.add(new Resumo("Fundos", 1000));  
         res.add(new Resumo("Renda Fixa", 0));  
         res.add(new Resumo("Renda var", 0));             
         teste(res, 0);  
     }  

E pronto…