Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

dúvida com o método forEach usando lambda no java8

Boa noite galera, tenho uma dúvida sobre o escopo de variável no foreach, o código abaixo não compila, pois não aceita a variável soma como sendo uma variável local, o código só compila se eu colocar a vai;aval soma como atributo da classe, porque isso acontece?

//classe simples 
class Produto{
    private int id;
    public int getID(){
        return id;
    }
}

class Cesto{
    List<Produto> produtos = new ArrayList<Produto>();
    public int getQuantidadeProduto(Produto produto){
        int soma = 0;
        produtos.forEach(p->{
            if(p.getID() == produto.getID()) 
                soma++;  //erro aqui
        });
        return soma;
    }
}
2 respostas
solução!

Na verdade o problema não está relacionado ao escopo da variável.

No Java, se vc está acessando uma variável externa a um lambda, você precisa declarar ela como final.

Note que variáveis final se comportam como constantes, então a soma não poderá ter seu valor alterado, portanto o soma++ não irá funcionar.

Se você colocar soma como atributo da classe irá funcionar devido ao fato que a JVM faz uma cópia das variáveis locais quando um lambda é criado, mas não acontece o mesmo para atributos de classe, estes podendo ser modificados livremente.

Você pode então tentar implementar esta lógica com for normal, ou então com o uso de streams e filter, se quiser praticar lambda.

O código com filters ficaria assim:

public long getQuantidadeProduto(Produto produto){
    // Gera uma stream de dados, filtra com o id do produto, e conta quantos sobraram:
    return produtos.stream()
        .filter(p -> p.getID() == produto.getID())
        .count();
 }

muito obrigado pela explicação.