java 8 中的质数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44366942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 08:08:04  来源:igfitidea点击:

Prime number in java 8

javajava-8primes

提问by user3310115

I was trying to write a simple prime number program in Java 8. Below is the program. I wanted to reduce the code in isPrime()as well. Is there something that filters the elements from 2to n/2, and then apply filter for n%i == 0which would make isPrimeirrelevant?

我试图用 Java 8 编写一个简单的素数程序。下面是程序。我也想减少代码isPrime()。是否有什么东西可以过滤元素从2to n/2,然后应用过滤器,n%i == 0这会变得isPrime无关紧要?

import static java.util.stream.Collectors.toList;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Stream1 {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 20);
        // Prime number 
        System.out.println(numbers.stream()
                             .filter(Stream1::isPrime)
                             .collect(toList()));
    }

    public static boolean isPrime(int number) {
        for (int i = 2; i <= number / 2; i++) {
            if (number % i == 0) {
                return false;
            }
        }
        return true;
    }
}

回答by Shashwat Kumar

IntStreamcan be used to generate integer stream

IntStream可用于生成整数流

public static boolean isPrime(int number) {
    return !IntStream.rangeClosed(2, number/2).anyMatch(i -> number%i == 0); 
}

or

或者

public static boolean isPrime(int number) {
    return IntStream.rangeClosed(2, number/2).noneMatch(i -> number%i == 0);
}

回答by rossum

Your isPrime()is inefficient. First, you do not need to divide by any even numbers greater than 2, since an initial division by 2 will catch all even non-primes. Second, you terminate your loop at number / 2instead of the more efficient sqrt(number).

isPrime()的效率低下。首先,您不需要除以任何大于 2 的偶数,因为初始除以 2 将捕获所有偶数非素数。其次,您将循环终止于number / 2而不是更有效的sqrt(number)

You could rewrite your method something like this:

你可以像这样重写你的方法:

public static boolean isPrime(int number) {

    // Even numbers
    if (number % 2 == 0) {
        return number == 2;
    }

    // Odd numbers
    int limit = (int)(0.1 + Math.sqrt(number));
    for (int i = 3; i <= limit; i += 2) {
        if (number % i == 0) {
            return false;
        }
    }
    return true;
}

The Sieve of Eratosthenes would be more efficient still, but that might be overkill for a relatively small problem.

Eratosthenes 的筛子仍然会更有效,但对于一个相对较小的问题来说这可能是过度的。

回答by Eugene

As suggest by @rossum you can use the famous Sieve of Eratosthenesfor this and it will compute the primes pretty fast.

正如@rossum 所建议的,您可以为此使用著名的 Eratosthenes 筛,它会非常快地计算素数。

 private static BitSet primes(int limit) {
    BitSet bitSet = new BitSet(limit);
    bitSet.set(0, false);
    bitSet.set(1, false);
    bitSet.set(2, limit, true);

    for (int i = 2; i * i < limit; ++i) {

        if (bitSet.get(i)) {
            int j = i;
            int x = 2;
            while (j < limit) {
                j = i * x;
                bitSet.set(j, false);
                ++x;
            }
        }

    }

    return bitSet;
}

回答by Deep

You can achieve the desired using predicate as well.

您也可以使用谓词实现所需的效果。

import java.util.Arrays;
import java.util.List;
import java.util.function.IntPredicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class PrimeUsingStream {

     public static boolean isPrime(int i) {
            IntPredicate isDivisible = index -> i % index == 0;
            return i > 1 && IntStream.range(2, i).noneMatch(isDivisible);
     }

     public static void main(String[] args) 
     {

        //System.out.println(printPrime(200));

         List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 20,23);
            // Prime number 
        System.out.println(numbers.stream()
                                 .filter(PrimeUsingStream::isPrime)
                                 .collect(Collectors.toList()));
     }

}

回答by S. Zror

You can use stream as this test below:

您可以使用流作为下面的测试:

@Test
public void generatePrimeNumberListByStream(){
    List<Integer> primeNumbers =
            IntStream
                    .range(2,30)
                    .filter(number -> IntStream.range(2,number)
                            .noneMatch(divider -> number % divider == 0))
                    .boxed()
                    .collect(Collectors.toList());
    assertThat(primeNumbers, contains(2,3,5,7,11,13, 17,19, 23, 29));
}