digitalinnovationone / ganhando_produtividade_com_Stream_API_Java

Este repositório contém o código-fonte do curso "Ganhando Produtividade com Stream API Java". O curso foi projetado para ajudar desenvolvedores Java a aproveitar ao máximo a poderosa Stream API introduzida no Java 8.
https://web.dio.me/course/ganhando-produtividade-com-stream-api
794 stars 497 forks source link

Duvida no desafio 5 #2

Closed JKaio2003 closed 1 year ago

JKaio2003 commented 1 year ago

Desafio 05

Não sei como tirar a média com Stream API, a única coisa que consigo fazer é somar todos os valores. Acredito que exista uma forma de fazer isso diretamente pelo Stream API, só não sei como :/

    List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 4, 3);

    int media = numeros.stream()
            .reduce(0 , (n1, n2) -> n1 + n2);

    System.out.println(media);
cami-la commented 1 year ago

Oi, @JKaio2003. Tudo certinho?

Então, quando você está utilizando o reduce(), você não está calculando a média e sim calculando a soma de todos os elementos de dentro da lista.

A implementação do reduce() está correta, parabéns! Agora só falta calcular a média:

    List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 4, 3);

    //somar todos os números
    Integer soma = numeros.stream().reduce(0, Integer::sum);

    //Calculando a média e imprimindo (soma total dividida pela quantidade de elementos)
    System.out.println(soma / numeros.size());

Porém tem um detalhe: como o total da soma está como Integer, e o cálculo da média é o resultado de uma divisão, se você deixar a soma como Inteiro, você não irá conseguir pegar os "números quebrados" caso a divisão não seja exata.

Em resumo, para essa média ficar mais assertiva, você pode converter o resultado da soma para o tipo Double:

List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 4, 3);

    //somar todos os números
    Double soma = numeros.stream()
        .map(Integer::doubleValue)
        .reduce(0d, Double::sum);

    //Calculando a média e imprimindo (soma total dividida pela quantidade de elementos)
    System.out.println(soma / numeros.size());

Segue outra solução caso você não queira utilizar o reduce(). O método mapToDouble() que com ele você tem um outro método chamado average():

List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 4, 3);

        double media = numeros.stream()
            .mapToDouble(Integer::doubleValue)
            .average()
            .ifPresent(System.out::println);

Aqui também tem várias implementações que podem te ajudar a responder os outros desafios: https://github.com/cami-la/curso-dio-intro-collections/blob/master/src/br/com/dio/collection/streamAPI/ExerciciosStreamAPI.java