[英]Java 8 How to check if one number is divided by more than 1 number using Stream
How can i check if one range from numbers is divided by more than one number. 我如何检查数字的一个范围是否除以一个以上的数字。 For example if it is only 1 divisor this will work , but i don't know what to do when i have an array from numbers :
例如,如果只有1个除数,它将起作用,但是当我有一个数字数组时,我不知道该怎么做:
int limitNumber = 10;
int onlyOneDivisor = 2;
String input = "2 3";
int[] nums = Arrays.stream(input.split(" ")).mapToInt(Integer::parseInt).toArray();
//This works fine, but it's divided only by 2 //效果很好,但只除以2
IntStream.rangeClosed(0, limitNumber).filter(n -> (n % onlyOneDivisor == 0))
.forEach(x -> System.out.print(x + " "));
You can use filter
, filtering by another stream over all the divisors, and using allMatch
or anyMatch
, depending on the exact use case: 您可以使用
filter
,通过所有除数上的另一个流进行过滤,并根据实际用例使用allMatch
或anyMatch
:
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);
If you want to check whether a number has exactly two divisors (given a list of more than two), you could use an inner filter
and combine that with count
: 如果要检查一个数字是否恰好有两个除数(给出两个以上的列表),则可以使用内部
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);
Note, however, that if you want to find prime numbers, you should probably not use a fixed list of divisors, but determine the divisors from the number under test: 但是请注意,如果要查找质数,则可能不应该使用固定的除数列表,而应根据被测数确定除数:
IntStream.rangeClosed(0, max)
.filter(n -> IntStream.range(2, n).allMatch(d -> n % d != 0))
.forEach(System.out::println);
(Using n
as the upper bound here is not very efficient; sqrt(n)
would be enough, and only the odd numbers and two, and many more optimization.) (在此处使用
n
作为上限不是很有效; sqrt(n)
就足够了,只需要奇数和2以及更多优化即可。)
You could apply one filter
per divisor. 您可以为每个除数应用一个
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 + " "));
To do it in one go you need to check for divisibility by all factors at once. 要一次性完成,您需要同时检查所有因素的可分割性。 It's a bit much to write out inline, so I recommend a helper method
isDivisibleByAll
(implementation left as an exercise). 内联写很多,所以我推荐一个辅助方法
isDivisibleByAll
(作为练习isDivisibleByAll
实现)。
IntStream.rangeClosed(0, limitNumber)
.filter(n -> isDivisibleByAll(n, divisors))
.forEach(x -> System.out.print(x + " "));
A smarter approach might be to compute the least common multiple of the factors, then just check for divisibility by that number. 一个更聪明的方法可能是计算因子的最小公倍数 ,然后仅检查该数字的可除性。
I would use allMatch
within filter
: 我会在
filter
使用allMatch
:
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
Here I'm streaming over the divisors
array within filter
, to check that all divisors actually divide the current number. 在这里,我对
filter
的divisors
数组进行流式处理,以检查所有除数是否实际除以当前数。 If this condition is successful, the number remains in the stream and is finally printed. 如果此条件成功,该数字将保留在流中并最终被打印。
"Divided by more than 1 number" means it's not prime , so: “除以1以上的数字”表示它不是素数 ,因此:
IntStream.rangeClosed(0, limitNumber)
.filter(this::isNotPrime)
.forEach(x -> System.out.print(x + " "));
Then define a method: 然后定义一个方法:
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.