1
resposta

[Projeto] Desafio Streams

public class Produto {
    private String nome;
    private double preco;
    private String categoria;

    public Produto(String nome, double preco, String categoria) {
        this.nome = nome;
        this.preco = preco;
        this.categoria = categoria;
    }

    public String getNome() {
        return nome;
    }

    public double getPreco() {
        return preco;
    }

    public String getCategoria() {
        return categoria;
    }

    @Override
    public String toString() {
        return "Produto{" +
                "nome='" + nome + '\'' +
                ", preco=" + preco +
                ", categoria='" + categoria + '\'' +
                '}';
    }
}
public class Pessoa {
    String nome;
    int idade;

    Pessoa(String nome, int idade) {
        this.nome = nome;
        this.idade = idade;
    }

    public String getNome() {
        return nome;
    }

    public int getIdade() {
        return idade;
    }

    @Override
    public String toString() {
        return "Pessoa " +
                " nome='" + nome ;
    }
}
import java.util.*;

public class Main {
    static void main() {
        List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6);
        System.out.println(numeros.stream().filter(n -> n%2 == 0 ).toList());
        List<String> palavras = Arrays.asList("java", "stream", "lambda");
        System.out.println(palavras.stream().map(p -> p.toUpperCase()).toList());
        List<Integer> numeross = Arrays.asList(1, 2, 3, 4, 5, 6);
        List<Integer> numerosImparesMulti = numeross.stream().filter(n -> n%2 ==1).map(n -> n*2).toList();
        System.out.println(numerosImparesMulti);
        List<String> palavrass = Arrays.asList("apple", "banana", "apple", "orange", "banana");
        Set<String> palavrasSemDuplicadas = new HashSet<>(palavrass);
        System.out.println(palavrasSemDuplicadas);
        /// numeros primos
        List<List<Integer>> listaDeNumeros = Arrays.asList(
                Arrays.asList(1, 2, 3, 4),
                Arrays.asList(5, 6, 7, 8),
                Arrays.asList(9, 10, 11, 12)
        );
        List<Integer>listaAninhada = listaDeNumeros.stream()
                .flatMap(List::stream)
                .toList();

         var numerosPrimos = listaAninhada.stream()
                .map(n ->{
                    if(n <=1 ) {return false;}

                    for (int i = 2; i*i <= n; i++) {
                        if(n %i==0) return false;

                    }
                    return n;
                }).toList();


        System.out.println(numerosPrimos);



        List<Pessoa> pessoas = Arrays.asList(
                new Pessoa("Alice", 22),
                new Pessoa("Bob", 17),
                new Pessoa("Charlie", 19)
        );

       var pessoasFiltradas = pessoas.stream()
                .filter(p ->p.getIdade() >= 18).sorted(Comparator.comparing(pessoa -> pessoa.getNome())).toList();

        System.out.println(pessoasFiltradas);



        List<Produto> produtos = Arrays.asList(
                new Produto("Smartphone", 800.0, "Eletrônicos"),
                new Produto("Notebook", 1500.0, "Eletrônicos"),
                new Produto("Teclado", 200.0, "Eletrônicos"),
                new Produto("Cadeira", 300.0, "Móveis"),
                new Produto("Monitor", 900.0, "Eletrônicos"),
                new Produto("Mesa", 700.0, "Móveis")
        );

      List<Produto>produtosFiltrados =  produtos.stream()
                .filter(p -> p.getCategoria().equalsIgnoreCase("Eletrônicos"))
              .filter(p -> p.getPreco() <= 100000.00)
              .sorted(Comparator.comparing(Produto::getPreco)).limit(3)
              .toList();


        System.out.println(produtosFiltrados);





    }
}
1 resposta

Olá, Weid. Como vai?

Excelente resolução do desafio! Como desenvolvedor back-end, você já deve estar percebendo o quanto a Stream API do Java 8+ transforma a manipulação de coleções, deixando o código muito mais expressivo, declarativo e alinhado com o paradigma funcional.

A sua implementação passou com sucesso por cenários complexos, como o uso de filter, map, ordenação com sorted, agrupamento de listas com flatMap e limitação de resultados com limit.

Analisando o seu código de forma refinada, vale destacar um detalhe técnico no desafio dos números primos e propor uma otimização com boas práticas para os filtros dos produtos.

O Desafio dos Números Primos (map vs filter)

No trecho onde você busca os números primos dentro da listaAninhada, você utilizou a operação .map(...). O comportamento do map é transformar um dado em outro dado mantendo a mesma quantidade de elementos. No seu código, quando o número não é primo, você retorna false (um booleano), e quando é primo, você retorna o próprio número n (um inteiro).

Isso faz com que a lista final numerosPrimos se torne uma lista mista de tipos ou objetos, contendo valores como [false, 2, 3, false, 5, false, 7...].

Para obter uma lista contendo apenas os números primos, a boa prática é isolar a lógica de verificação em um método auxiliar que retorna um booleano e passá-lo dentro de um .filter(...). Veja como fica mais elegante:

// Método auxiliar para verificar se é primo
public static boolean ehPrimo(int n) {
    if (n <= 1) return false;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

// Execução na Stream
List<Integer> numerosPrimos = listaAninhada.stream()
        .filter(Main::ehPrimo) // Filtra mantendo apenas os que retornam true
        .toList();

Otimização no Filtro de Produtos

No bloco de produtos, o seu segundo filtro está verificando se o preço é menor ou igual a 100.000,00 (p.getPreco() <= 100000.00). Como todos os produtos da sua lista estão bem abaixo desse valor, o filtro acaba não surtindo um efeito prático de corte. Se o objetivo do desafio era filtrar produtos mais baratos (por exemplo, abaixo de 1.000,00), você pode ajustar o valor limite para tornar o limit(3) mais desafiador para o algoritmo.

Além disso, você pode encadear os filtros em uma única expressão lógica dentro do mesmo filter, o que reduz a criação de múltiplos estágios na pipeline da Stream:

List<Produto> produtosFiltrados = produtos.stream()
        .filter(p -> p.getCategoria().equalsIgnoreCase("Eletrônicos") && p.getPreco() <= 1000.00)
        .sorted(Comparator.comparing(Produto::getPreco))
        .limit(3)
        .toList();

Dominar essa combinação de predicados e funções de transformação é um diferencial enorme para construir APIs robustas e performáticas com o Spring Framework. Parabéns pelo nível das implementações!

Espero que possa ter lhe ajudado!