ganhando_produtividade_com_Stream_API_Java icon indicating copy to clipboard operation
ganhando_produtividade_com_Stream_API_Java copied to clipboard

Desafio 8

Open dor-95 opened this issue 2 years ago • 14 comments

Oi @cami-la , tudo bem?

Eu realizei a implementação do desafio 8, mais parece estar complexo, ainda não consegui pensar em uma forma de melhorar. Sabe me dizer outra forma de resolver?

Minha implementação:

Desafio 8 - Somar os dígitos de todos os números da lista: Utilizando a Stream API, realize a soma dos dígitos de todos os números da lista e exiba o resultado no console.

List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 4, 3, 11, 28, 35, 180, 110, 200, 245);

    int resultado = numeros.stream().mapToInt(n -> {
        if (n / 10 == 0) return n;
        int sum = 0;
        int length = String.valueOf(n).length();
        for (int i = 0; i < length; i++) {
            sum += n % 10;
            n = n / 10;
        }
        return sum;
    }).sum();

    System.out.println("A soma dos dígitos de todos os números da lista é: " + resultado);`

dor-95 avatar Sep 19 '23 13:09 dor-95

Só usar o reduce:

numeros.stream().reduce(0, Integer::sum);

ou

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

jeziel-almeida avatar Sep 19 '23 20:09 jeziel-almeida

acho que vc pode remover aquele if do começo, e retornar apenas sum. Eu fiz assim

int somaDigitos = numeros.stream().mapToInt(n1 -> {
            int sum = 0, length = String.valueOf(n1).length();
            for (int i = 0; i < length; i++) {
                sum += n1 % 10;
                n1 /= 10;
            }
            return sum;
        }).sum();

o sum retorna 0 se o numero em questão nao existir, pois o for já faz essa verificação, se o numero não existir ele passa direto pelo laço e retorna 0

Saul-Medeiros avatar Oct 15 '23 02:10 Saul-Medeiros

Então @Saul-Medeiros, pelo que pude perceber o IF acaba realizando a conferência quando o número possui apenas 1 dígito, não sendo necessário entrar uma vez no laço do FOR e retornando ele mesmo para fazer parte da soma. Ou seja, ele acaba economizando algumas interações do FOR.

dor-95 avatar Oct 17 '23 00:10 dor-95

neste caso, não passando pelo laço ele seria mais rápido 🤔? é pq na minha concepção quanto menos código vc escrever é melhor, e pra cada número que o mapForInt* for testar ele vai ser obrigado a passar por esse if e pelo próprio for. No caso do seu código ele vai retornar o numero quando o tamanho dele for 0, ou seja inexistente. Se por via das dúvidas ainda tiver um "null" no array, acredito que poderia lançar uma exception.

Saul-Medeiros avatar Oct 17 '23 00:10 Saul-Medeiros

Rapaz, nem tinha parado para testar o tempo, agora fiz um teste básico com o System.currentTimeMillis(), no array que ta ali nessa descrição com e sem o if o resultado foi 0 ms. Pode ser que fique melhor sem o IF mesmo, mais legível.

Nesse exercício, como temos que somar todos os dígitos, esse IF verifica quantos dígitos tem o número e caso ele tenha apenas um (exemplo: 5) ele já retorna esse resultado devido o return, debuguei no Intellij pra ver kk. Agora no caso de algum número com mais de um dígito (exemplo: 245), ele segue para o FOR para decompor e realizar a somatório. No caso de ter um null, ele lança a exceção com ou sem o IF.

dor-95 avatar Oct 17 '23 02:10 dor-95

Olá, Camila. Fiquei com dúvida se a resolução esta certa. Até vi os comentarios dos outros colegas mas ainda sim não tenho certeza se segui a linha de raciocinio correta image

Leticiassb avatar Jun 08 '24 02:06 Leticiassb

Olá, Camila. Fiquei com dúvida se a resolução esta certa. Até vi os comentarios dos outros colegas mas ainda sim não tenho certeza se segui a linha de raciocinio correta image

Certinho, @Leticiassb. O Reduce vai passar pela lista pegando todos os números e ir somando um a um.

cami-la avatar Jun 10 '24 18:06 cami-la

Olá Camila. Neste desafio o correto seria apenas somar cada número da lista ou somar cada dígito de cada numero da lista, fiquei em dúvida??

odairsp avatar Aug 14 '24 13:08 odairsp

Bom dia a todos, eu fiz das duas maneiras, tanto somando todos os números da lista, quanto a soma de todos os digitos de cada número, fiz uma conversão para String. Segue abaixo as implementações que realizei: resolução

Mateusf95 avatar Sep 04 '24 14:09 Mateusf95

Minha solução é mais simples mas é limitada a números de até 2 dígitos, ao contrário das soluções acima.

    System.out.println("challenge 08: " +
        numeros.stream()
            .mapToInt(i -> i / 10 + i % 10)
            .sum());

Achei bem interessante a abordagem do @Mateusf95. Não conhecia o método getNumericValue() e achei um exemplo na Internet usando um código Unicode para o número 50 em algarismos romanos (e eu sequer imaginava que houvesse um caractere específico para o número 50 em algarismos romanos em Unicode, achei que fosse um L maiúsculo convencional):

    int cinquentaEmRomanos = 0x216C;
    System.out.println(Character.toChars(cinquentaEmRomanos)[0]);
    System.out.println(Character.getNumericValue(Character.toChars(cinquentaEmRomanos)[0]));

alexdemoraes avatar Sep 05 '24 13:09 alexdemoraes

Olá estava verificando aqui a minha ficou bem enxuta vou mandar aqui int soma =numeros.stream() .mapToInt(Integer::intValue) .sum(); System.out.println(soma);

Senuy avatar Sep 06 '24 13:09 Senuy

Sua solução só está correta se for para somar os números da lista. Se for pra somar os dígitos dos números, vai ter que elaborar um pouquinho mais.

alexdemoraes avatar Sep 06 '24 13:09 alexdemoraes

Tente algo assim

   public Integer somarTodossNumeros(List<Integer> number){
       //identity valor inicial da variavel.
        //Integer::sum somar tudo
        return number.stream()
                .reduce(0, Integer::sum);
    }

Sync-BR avatar Nov 15 '24 17:11 Sync-BR