Especialização em Sistemas com Java 21 LTS • Capítulo 14


🎯 Visão Geral dos Exemplos Práticos

Neste laboratório prático, implementaremos exemplos corporativos completos explorando:

  1. Pipeline de Agrupamento Multidimensional com Collectors: agregação estatística de faturamento e média de tíquete por segmento de mercado.
  2. Transformações Avançadas com map, flatMap e reduce: desnormalização de itens de compras e consolidação contábil.
  3. Benchmark: Processamento Sequencial vs Paralelo (parallelStream): análise empírica de saturação de CPU com o pool ForkJoin.

💻 Exemplo 01 — Pipeline de Consolidação de Inteligência Financeira

package com.empresa.funcional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Inteligência de Negócios (BI) e Analytics com Java 21 Streams API.
 */
public class InteligenciaFinanceiraStreams {

    public enum CategoriaCliente { RETAIL, CORPORATE, WEALTH_MANAGEMENT }

    public record OperacaoInvestimento(
            String codigoTx,
            String cliente,
            CategoriaCliente categoria,
            BigDecimal valorAplicado,
            double taxaRetornoAnual,
            boolean aprovadaCompliance
    ) {}

    public static void main(String[] args) {
        System.out.println("================================================================================");
        System.out.println("         ANALYTICS DE INVESTIMENTOS COM STREAMS E COLLECTORS (JAVA 21)          ");
        System.out.println("================================================================================");

        List<OperacaoInvestimento> carteira = List.of(
            new OperacaoInvestimento("INV-01", "Alvorada Log", CategoriaCliente.CORPORATE, new BigDecimal("450000.00"), 0.125, true),
            new OperacaoInvestimento("INV-02", "Dra. Beatriz", CategoriaCliente.WEALTH_MANAGEMENT, new BigDecimal("1200000.00"), 0.142, true),
            new OperacaoInvestimento("INV-03", "Carlos Mendes", CategoriaCliente.RETAIL, new BigDecimal("15000.00"), 0.105, true),
            new OperacaoInvestimento("INV-04", "Fundo Gamma", CategoriaCliente.CORPORATE, new BigDecimal("850000.00"), 0.131, false), // Reprovada
            new OperacaoInvestimento("INV-05", "Marcos Silva", CategoriaCliente.RETAIL, new BigDecimal("45000.00"), 0.110, true),
            new OperacaoInvestimento("INV-06", "Holding Zenith", CategoriaCliente.WEALTH_MANAGEMENT, new BigDecimal("3400000.00"), 0.150, true)
        );

        // 1. Filtrar operações de compliance e agrupar por Categoria somando o capital
        Map<CategoriaCliente, BigDecimal> volumePorCategoria = carteira.stream()
                .filter(OperacaoInvestimento::aprovadaCompliance)
                .collect(Collectors.groupingBy(
                        OperacaoInvestimento::categoria,
                        Collectors.reducing(BigDecimal.ZERO, OperacaoInvestimento::valorAplicado, BigDecimal::add)
                ));

        System.out.println("📈 VOLUME TOTAL APROVADO POR SEGMENTO:");
        volumePorCategoria.forEach((cat, volume) -> 
            System.out.printf("   Segmento: %-18s | Capital Alocado: R$ %,12.2f%n", cat, volume));

        // 2. Média ponderada de rentabilidade por segmento
        System.out.println("\n📊 ESTATÍSTICAS E TÍQUETE MÉDIO POR SEGMENTO:");
        Map<CategoriaCliente, DoubleSummaryStatistics> estatisticasPorCategoria = carteira.stream()
                .filter(OperacaoInvestimento::aprovadaCompliance)
                .collect(Collectors.groupingBy(
                        OperacaoInvestimento::categoria,
                        Collectors.summarizingDouble(op -> op.valorAplicado().doubleValue())
                ));

        estatisticasPorCategoria.forEach((cat, stats) -> {
            System.out.printf("   ➡️ %-18s | Operações: %d | Média: R$ %,10.2f | Maior Aporte: R$ %,10.2f%n",
                    cat, stats.getCount(), stats.getAverage(), stats.getMax());
        });

        // 3. Top 3 Maiores Aportes Individuais
        System.out.println("\n🏆 TOP 3 MAIORES OPERAÇÕES INDIVIDUAIS:");
        carteira.stream()
                .filter(OperacaoInvestimento::aprovadaCompliance)
                .sorted(Comparator.comparing(OperacaoInvestimento::valorAplicado).reversed())
                .limit(3)
                .forEach(op -> System.out.printf("   [TX %s] %-18s (%s) : R$ %,12.2f | Retorno: %.1f%%%n",
                        op.codigoTx(), op.cliente(), op.categoria(), op.valorAplicado(), op.taxaRetornoAnual() * 100));

        System.out.println("================================================================================");
    }
}

💻 Exemplo 02 — Benchmark Comparativo: Stream Sequencial vs Paralelo

package com.empresa.funcional;

import java.util.List;
import java.util.stream.IntStream;

/**
 * Benchmark empírico de paralelização com ForkJoinPool.
 */
public class BenchmarkStreamsParalelas {

    private static boolean isPrimo(int numero) {
        if (numero <= 1) return false;
        for (int i = 2; i * i <= numero; i++) {
            if (numero % i == 0) return false;
        }
        return true;
    }

    public static void main(String[] args) {
        final int LIMITE = 1_000_000;
        System.out.println("================================================================================");
        System.out.println("          BENCHMARK: PROCESSAMENTO DE PRIMOS (SEQUENCIAL vs PARALELO)           ");
        System.out.println("================================================================================");
        System.out.printf("Calculando quantidade de números primos até %,d...%n%n", LIMITE);

        // 1. Execução Sequencial
        long t0 = System.currentTimeMillis();
        long totalPrimosSeq = IntStream.rangeClosed(1, LIMITE)
                .filter(BenchmarkStreamsParalelas::isPrimo)
                .count();
        long t1 = System.currentTimeMillis();
        long tempoSeq = t1 - t0;

        // 2. Execução Paralela (Usa todos os núcleos da CPU via ForkJoinPool)
        long t2 = System.currentTimeMillis();
        long totalPrimosPar = IntStream.rangeClosed(1, LIMITE)
                .parallel()
                .filter(BenchmarkStreamsParalelas::isPrimo)
                .count();
        long t3 = System.currentTimeMillis();
        long tempoPar = t3 - t2;

        System.out.printf("1. Stream Sequencial : %5d ms | Primos Encontrados: %,d%n", tempoSeq, totalPrimosSeq);
        System.out.printf("2. Stream Paralela   : %5d ms | Primos Encontrados: %,d%n", tempoPar, totalPrimosPar);
        System.out.printf("🚀 Speedup da Paralelização: %.2fx mais rápido!%n", (double) tempoSeq / Math.max(tempoPar, 1));
        System.out.println("================================================================================");
    }
}

📋 Resultado Esperado no Console

================================================================================
         ANALYTICS DE INVESTIMENTOS COM STREAMS E COLLECTORS (JAVA 21)          
================================================================================
📈 VOLUME TOTAL APROVADO POR SEGMENTO:
   Segmento: CORPORATE          | Capital Alocado: R$   450.000,00
   Segmento: RETAIL             | Capital Alocado: R$    60.000,00
   Segmento: WEALTH_MANAGEMENT  | Capital Alocado: R$ 4.600.000,00

📊 ESTATÍSTICAS E TÍQUETE MÉDIO POR SEGMENTO:
   ➡️ CORPORATE          | Operações: 1 | Média: R$ 450.000,00 | Maior Aporte: R$   450.000,00
   ➡️ RETAIL             | Operações: 2 | Média: R$  30.000,00 | Maior Aporte: R$    45.000,00
   ➡️ WEALTH_MANAGEMENT  | Operações: 2 | Média: R$ 2.300.000,00 | Maior Aporte: R$ 3.400.000,00

🏆 TOP 3 MAIORES OPERAÇÕES INDIVIDUAIS:
   [TX INV-06] Holding Zenith     (WEALTH_MANAGEMENT) : R$ 3.400.000,00 | Retorno: 15.0%
   [TX INV-02] Dra. Beatriz       (WEALTH_MANAGEMENT) : R$ 1.200.000,00 | Retorno: 14.2%
   [TX INV-01] Alvorada Log       (CORPORATE)         : R$   450.000,00 | Retorno: 12.5%
================================================================================

================================================================================
          BENCHMARK: PROCESSAMENTO DE PRIMOS (SEQUENCIAL vs PARALELO)           
================================================================================
Calculando quantidade de números primos até 1,000,000...

1. Stream Sequencial :   185 ms | Primos Encontrados: 78,498
2. Stream Paralela   :    38 ms | Primos Encontrados: 78,498
🚀 Speedup da Paralelização: 4.87x mais rápido!
================================================================================