Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
2
respostas

[Projeto] DESAFIO

6, 7, 8 E 9.

PRINCIPAL

package br.com.projetoalura.br.com.projetoalura.SEIS;

import br.com.projetoalura.SEIS.Produto;

import java.util.*;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        
        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")
        );

        System.out.println("--- RESULTADOS DOS EXERCÍCIOS ---");


        Map<String, List<Produto>> porCategoria = produtos.stream()
                .collect(Collectors.groupingBy(Produto::getCategoria));
        System.out.println("\n6. Produtos por Categoria: " + porCategoria);


        Map<String, Long> contagemPorCategoria = produtos.stream()
                .collect(Collectors.groupingBy(Produto::getCategoria, Collectors.counting()));
        System.out.println("\n7. Quantidade por Categoria: " + contagemPorCategoria);


        Map<String, Optional<Produto>> maisCaroPorCategoria = produtos.stream()
                .collect(Collectors.groupingBy(Produto::getCategoria,
                        Collectors.maxBy(Comparator.comparingDouble(Produto::getPreco))));
        System.out.println("\n8. Mais caro por Categoria: " + maisCaroPorCategoria);

        Map<String, Double> somaPorCategoria = produtos.stream()
                .collect(Collectors.groupingBy(Produto::getCategoria,
                        Collectors.summingDouble(Produto::getPreco)));
        System.out.println("\n9. Valor Total por Categoria: " + somaPorCategoria);

        List<Produto> filtroEspecial = produtos.stream()
                .filter(p -> p.getCategoria().equals("Eletrônicos"))
                .filter(p -> p.getPreco() < 1000)
                .sorted(Comparator.comparingDouble(Produto::getPreco))
                .collect(Collectors.toList());
        System.out.println("\nEXTRA. Filtro Eletrônicos < 1000: " + filtroEspecial);
    }
}

PRODUTO

package br.com.projetoalura.SEIS;

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 nome + " (R$ " + preco + ")";
    }
}

1

package br.com.projetoalura.UM;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        List<Integer> numeros = Arrays.asList(10, 20, 30, 40, 50);
        Optional<Integer> max = numeros.stream()
                .max(Integer::compare);
        max.ifPresent(System.out::println);
    }
}

2

package br.com.projetoalura.DOIS;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<String> palavras = Arrays.asList("java", "stream", "lambda", "code");
        Map<Integer, List<String>> agrupamento = palavras.stream()
                .collect(Collectors.groupingBy(String::length));
        System.out.println(agrupamento);

    }
}

3

public class Main {
    public static void main(String[] args) {
        List<String> nomes = Arrays.asList("Alice", "Bob", "Charlie");
        String resultado = nomes.stream()
                .collect(Collectors.joining(", "));
        System.out.println(resultado);
    }
}

4

public class Main {
    public static void main(String[] args) {
        List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6);
        int somaDosQuadrados = numeros.stream()
                .filter(n -> n % 2 == 0)
                .map(n -> n * n)
                .reduce(0, Integer::sum);
        System.out.println(somaDosQuadrados);
    }
}

5

public class Main {
    public static void main(String[] args) {
        List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6);
        Map<Boolean, List<Integer>> particionado = numeros.stream()
                .collect(Collectors.partitioningBy(n -> n % 2 == 0));
        System.out.println("Pares: " + particionado.get(true));
        System.out.println("Ímpares: " + particionado.get(false));
    }
}
2 respostas
solução!

Olá, Giulia. Como vai?

Parabéns pela excelente resolução do desafio! O seu código demonstra um domínio muito sólido dos conceitos de Streams API, expressões Lambda e Method References em Java. Você conseguiu aplicar corretamente desde operações básicas de redução até agrupamentos complexos e downstream collectors.

Para enriquecer ainda mais o seu aprendizado e trazer valor para os outros estudantes que estão acompanhando este tópico, vale a pena destacar alguns pontos excelentes da sua solução e uma dica de boa prática:

  • Uso do Collectors.groupingBy com Downstream (Exercícios 7, 8 e 9): Essa é uma das ferramentas mais poderosas da Streams API. Em vez de apenas agrupar os elementos em uma lista, você utilizou corretamente coletores secundários como Collectors.counting(), Collectors.maxBy() e Collectors.summingDouble(). Isso reduz drasticamente a necessidade de loops e estruturas condicionais manuais, deixando o código muito mais declarativo.
  • Diferença entre groupingBy e partitioningBy (Exercícios 2 e 5): É muito legal ver os dois aplicados no seu projeto. Enquanto o groupingBy (exercício 2 e principais) cria um mapa com chaves dinâmicas baseadas na função classificadora, o partitioningBy (exercício 5) é uma especialização que sempre divide a coleção em apenas dois grupos (chaves true e false) com base em um predicado booleano, o que é ideal para separações binárias como pares e ímpares.
  • Filtro Extra Otimizado: No seu exercício extra, você encadeou dois métodos .filter(). Isso é perfeitamente válido e legível. Uma alternativa que muitos desenvolvedores utilizam para simplificar a expressão é unir as condições lógicas em um único predicado:
List<Produto> filtroEspecial = produtos.stream()
        .filter(p -> p.getCategoria().equals("Eletrônicos") && p.getPreco() < 1000)
        .sorted(Comparator.comparingDouble(Produto::getPreco))
        .collect(Collectors.toList());
  • Sugestão de Boa Prática (Java 16+): No exercício extra, você utilizou .collect(Collectors.toList()). Nas versões mais recentes do Java (a partir do Java 16), quando precisamos apenas de uma lista imutável, podemos simplificar a sintaxe utilizando diretamente o método .toList() ao final do fluxo:
List<Produto> filtroEspecial = produtos.stream()
        .filter(p -> p.getCategoria().equals("Eletrônicos") && p.getPreco() < 1000)
        .sorted(Comparator.comparingDouble(Produto::getPreco))
        .toList(); // Mais limpo e moderno

Seus pacotes e a estrutura da classe Produto com o método toString() customizado também ficaram ótimos, facilitando a leitura dos dados no console. Continue com esse excelente ritmo de estudos!

Espero que possa ter lhe ajudado!

Boa tarde, Evandro!! Tudo bem sim!!!

Fico muito feliz em saber que estou evoluindo bem. Espero continuar assim... estou muito animada com esse curso e com a minha evolução nele!
O Alura sendo sensacional, como sempre.

Muito obrigada pela ótima dica!!