Desafio Java
Processamento de transações com streams
Enunciado
Dada uma lista de transações (cada uma com id, tipo e valor), use streams para:
- Filtrar transações do tipo "CREDITO".
- Agrupar por id usando
Collectors.groupingBy. - Para cada grupo, somar os valores usando
Collectors.summingDouble. - Imprimir o mapa resultante (id -> soma).
Considere a classe Transacao já definida.
Requisitos
- Use
filterpara manter apenas transações do tipo "CREDITO". - Use
Collectors.groupingBycomTransacao::getIdcomo classificador. - Use
Collectors.summingDoublecomo coletor downstream. - Imprima o mapa ordenado por id (use
TreeMap).
Código inicial
import java.util.*;
import java.util.stream.*;
class Transacao {
private final int id;
private final String tipo;
private final double valor;
public Transacao(int id, String tipo, double valor) {
this.id = id;
this.tipo = tipo;
this.valor = valor;
}
public int getId() { return id; }
public String getTipo() { return tipo; }
public double getValor() { return valor; }
}
public class ExercicioDesafio {
public static void main(String[] args) {
List<Transacao> transacoes = Arrays.asList(
new Transacao(1, "CREDITO", 100.0),
new Transacao(2, "DEBITO", 50.0),
new Transacao(1, "CREDITO", 200.0),
new Transacao(3, "CREDITO", 300.0),
new Transacao(2, "CREDITO", 150.0)
);
// Complete aqui
}
}
Saída esperada
{1=300.0, 2=150.0, 3=300.0}
Ver dica
Use Collectors.groupingBy(Transacao::getId, TreeMap::new, Collectors.summingDouble(Transacao::getValor)).
Mostrar solução
import java.util.*;
import java.util.stream.*;
class Transacao {
private final int id;
private final String tipo;
private final double valor;
public Transacao(int id, String tipo, double valor) {
this.id = id;
this.tipo = tipo;
this.valor = valor;
}
public int getId() { return id; }
public String getTipo() { return tipo; }
public double getValor() { return valor; }
}
public class ExercicioDesafio {
public static void main(String[] args) {
List<Transacao> transacoes = Arrays.asList(
new Transacao(1, "CREDITO", 100.0),
new Transacao(2, "DEBITO", 50.0),
new Transacao(1, "CREDITO", 200.0),
new Transacao(3, "CREDITO", 300.0),
new Transacao(2, "CREDITO", 150.0)
);
Map<Integer, Double> somaPorId = transacoes.stream()
.filter(t -> "CREDITO".equals(t.getTipo())) // apenas créditos
.collect(Collectors.groupingBy(
Transacao::getId, // agrupa por id
TreeMap::new, // mapa ordenado
Collectors.summingDouble(Transacao::getValor) // soma os valores
));
System.out.println(somaPorId);
}
}
Passo a passo
- Criamos uma lista de transações com id, tipo e valor.
transacoes.stream()cria um stream.filter(t -> "CREDITO".equals(t.getTipo()))mantém apenas transações do tipo "CREDITO".collect(Collectors.groupingBy(...))agrupa as transações filtradas.- O primeiro argumento de
groupingByéTransacao::getId, que extrai o id como chave. - O segundo argumento
TreeMap::newespecifica que o mapa resultante será umTreeMap, garantindo ordenação pelas chaves. - O terceiro argumento
Collectors.summingDouble(Transacao::getValor)é o coletor downstream que soma os valores de cada grupo. - O resultado é impresso.
Por que funciona
A combinação de filter com groupingBy e um coletor downstream permite processar e agregar dados em uma única passagem. O stream é preguiçoso, então as operações só são executadas quando collect é chamado. O uso de TreeMap garante que as chaves (ids) estejam ordenadas, o que é útil para apresentação.
Erros comuns
- Esquecer de importar
java.util.stream.Collectors. - Usar
Collectors.summingIntousummingLongquando os valores sãodouble, causando erro de compilação. - Não fornecer o terceiro argumento para
groupingBye depois tentar usarTreeMap, resultando em umHashMapnão ordenado. - Filtrar após agrupar: isso não funcionaria corretamente porque o agrupamento já teria incluído todos os tipos.
Outra forma de resolver
Se não precisar de ordenação, omita o TreeMap:
Map<Integer, Double> somaPorId = transacoes.stream()
.filter(t -> "CREDITO".equals(t.getTipo()))
.collect(Collectors.groupingBy(Transacao::getId, Collectors.summingDouble(Transacao::getValor)));
Isso é mais simples, mas a ordem das chaves não é garantida.
Saída esperada
{1=300.0, 2=150.0, 3=300.0}