ganhando_produtividade_com_Stream_API_Java
ganhando_produtividade_com_Stream_API_Java copied to clipboard
Desafio 8
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);`
Só usar o reduce:
numeros.stream().reduce(0, Integer::sum);
ou
numeros.stream().reduce(0, (n1, n2) -> n1 + n2);
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
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.
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.
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.
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
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
Certinho, @Leticiassb. O Reduce vai passar pela lista pegando todos os números e ir somando um a um.
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??
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:
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]));
Olá estava verificando aqui a minha ficou bem enxuta vou mandar aqui
int soma =numeros.stream()
.mapToInt(Integer::intValue)
.sum();
System.out.println(soma);
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.
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);
}
