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
558 stars 344 forks source link

Desafio 14 #11

Open LoostSoull opened 9 months ago

LoostSoull commented 9 months ago

Ola @cami-la , tudo bem?

travei no desafio 14, encontrei um aluno que fez um codigo genial:


 Optional<Integer> maiorPrimo = numeros.stream()
                .filter(n -> {
                    if (Math.abs(n) < 2)
                        return false;
                    for (int i = 2; i < Math.abs(n); i++) {
                        if (Math.abs(n) % i == 0)
                            return false;
                    }
                    return true;
                })
                .max(Comparator.naturalOrder());
        System.out.println("O maior número primo é: " + maiorPrimo.get());
    }

testei e funcionou, porem nao entendi, porque ele utilizou o Math.abs, pesquisei sobre essa função, e ela serve para retornar o valor absoluto, como utilizamos divisao com mod zero, seria mesmo necessario? não entend o fato delle utilizar tambem : .filter(n -> { if (Math.abs(n) < 2) return false; , qual seria o sentido de comprar se o valor absoluto de "n" por exemplo da lista, se o valor absoluto de 2 é menor que 2? e caso seja, retorne false e por ai segue o codigo dele, poderia me explicar o codigo dele, assim posso tentar entender a logica dele

andersoncpdq commented 9 months ago

Olá, não sou a Cami, mas posso ajudar kkk.

Os números primos são aqueles que apresentam apenas dois divisores: um e o próprio número. E precisam ser maiores do que um. Na primeira verificação, ele testa se o número corrente é o próprio 1 (n < 2). Como o número 1 não é primo, logo retorna falso. Caso não seja o número 1, ele verifica se o número corrente é divisível pelo contador, no intervalo de 2 até n-1. Portanto, ele acaba filtrando só os números primos.

Quanto ao uso do abs(), acho que foi só pra 'enfeitar' o código...caso tenho algum número negativo na lista. Pro exemplo que a Cami passou, realmente não é necessário.

cami-la commented 9 months ago

Então, vamos lá.

  1. Definição de um número primo: Um número primo é definido como um número inteiro maior do que 1 que não pode ser dividido por nenhum outro número inteiro, exceto 1 e ele mesmo.
  2. Antes de verificar se um número é primo ou não, é necessário garantir que ele seja positivo. A função Math.abs() (valor absoluto) é usada para fazer isso. De fato é necessário fazer essa verificação.
  3. Achei interessante, viu? Eu não tinha pensando em fazer dessa forma. Até porque tem um método clássico de verificar se o número é primo:
 // Função que verifica se um número é primo
    public static boolean isPrimo(int n) {
        // Verifica se o número é menor ou igual a 1, caso contrário, não é primo
        if (n <= 1) {
            return false;
        }
        // Faz um loop de 2 até a raiz quadrada do número
        for (int i = 2; i * i <= n; i++) {
            // Se o número for divisível por algum valor no intervalo, não é primo
            if (n % i == 0) {
                return false;
            }
        }
        // Se não foi encontrado divisor no loop, o número é primo
        return true;
    }
  1. Aí, como você me lembrou do método Math.abs(), podemos fazer o seguinte:
        List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 4, 3);

        // Cria uma nova lista que conterá os números primos usando a Stream API
        List<Integer> numerosPrimos = numeros.stream()
                // Usa o método filter para selecionar apenas os números que atendem à condição
                // definida pelo predicado isPrimo
                .filter(Main::isPrimo) // A função Main::isPrimo refere-se ao método isPrimo na classe Main
                // Coleta os números filtrados em uma nova lista
                .collect(Collectors.toList());

        // Imprime a lista de números primos
        System.out.println("Números primos na lista: " + numerosPrimos);
    }

    public static boolean isPrimo(int n) {
    // Obtém o valor absoluto do número para garantir que seja positivo
    n = Math.abs(n);

    // Verifica se o número é menor ou igual a 1, caso contrário, não é primo
    if (n <= 1) {
        return false;
    }

    // Faz um loop de 2 até a raiz quadrada do número
    for (int i = 2; i * i <= n; i++) {
        // Se o número for divisível por algum valor no intervalo, não é primo
        if (n % i == 0) {
            return false;
        }
    }

    // Se não foi encontrado divisor no loop, o número é primo
    return true;
}
}

Respondi tua dúvida?

Drufontael commented 2 weeks ago

Usei um metodo parecido, só acrescentei um "if" antes do loop eliminando todos os pares exceto o 2 diminuirndo assim o numero de loops necessários.