Java 8如何使用Stream检查一个数字是否除以1以上的数字

时间:2017-06-25 14:53:36

标签: java java-8 java-stream

如何检查数字中的一个范围是否除以一个数字。例如,如果它只有1个除数,这将起作用,但是当我有数字数组时,我不知道该怎么做:

int limitNumber = 10;
int onlyOneDivisor = 2;
String input = "2 3";
int[] nums = Arrays.stream(input.split(" ")).mapToInt(Integer::parseInt).toArray();

//这样可以正常工作,但它只能分为2

IntStream.rangeClosed(0, limitNumber).filter(n -> (n % onlyOneDivisor == 0))
.forEach(x -> System.out.print(x + " "));

4 个答案:

答案 0 :(得分:3)

您可以使用filter,按照所有除数上的其他流进行过滤,并使用allMatchanyMatch,具体取决于具体用例:

int max = 10;
int[] divisors = {2, 3, 5};

// no divisor
IntStream.rangeClosed(0, max)
        .filter(n -> IntStream.of(divisors).allMatch(d -> n % d != 0))
        .forEach(System.out::println);

// any divisor
IntStream.rangeClosed(0, max)
        .filter(n -> IntStream.of(divisors).anyMatch(d -> n % d == 0))
        .forEach(System.out::println);

如果你想检查一个数字是否只有两个除数(给定一个超过两个的除数),你可以使用内部filter并将其与count结合使用:

// exactly two divisors
IntStream.rangeClosed(0, max)
        .filter(n -> IntStream.of(divisors).filter(d -> n % d == 0).count() == 2)
        .forEach(System.out::println);

但是,请注意,如果要查找素数,则可能不应使用固定的除数列表,而是从被测数中确定除数:

IntStream.rangeClosed(0, max)
        .filter(n -> IntStream.range(2, n).allMatch(d -> n % d != 0))
        .forEach(System.out::println);

(使用n作为上限不是很有效; sqrt(n)就够了,只有奇数和两个,还有更多优化。)

答案 1 :(得分:1)

您可以为每个除数应用一个filter

IntStream stream = IntStream.rangeClosed(0, limitNumber);

for (int divisor: divisors) {
    stream = stream.filter(n -> n % divisor == 0);
}

stream.forEach(x -> System.out.print(x + " "));

要一次性完成,您需要立即检查所有因素的可分性。写入内联有点多,所以我建议使用辅助方法isDivisibleByAll(实现作为练习)。

IntStream.rangeClosed(0, limitNumber)
    .filter(n -> isDivisibleByAll(n, divisors))
    .forEach(x -> System.out.print(x + " "));

更智能的方法可能是计算因素的least common multiple,然后只检查该数字的可分性。

答案 2 :(得分:1)

我会在allMatch中使用filter

String input = "2 3";

int[] divisors = Arrays.stream(input.split(" "))
    .mapToInt(Integer::parseInt)
    .toArray();

int limitNumber = 10;

IntStream.rangeClosed(0, limitNumber) // maybe 1 and not 0?
    .filter(n -> Arrays.stream(divisors).allMatch(d -> n % d == 0))
    .forEach(System.out::println); // 0 6

此处我在divisors内的filter数组上进行流式传输,以检查所有除数是否实际除以当前数字。如果此条件成功,则该数字将保留在流中并最终打印。

答案 3 :(得分:0)

"除以1个以上的数字"意味着它不是 prime ,所以:

IntStream.rangeClosed(0, limitNumber)
  .filter(this::isNotPrime)
  .forEach(x -> System.out.print(x + " "));

然后定义一个方法:

private boolean isNotPrime(int n) {
    int s = (int)Math.sqrt(n);
    for (int i = 2; i < s; i++)
        if (n % 2 == 0) return true;
    return false;
}