Title: Count Composite Numbers in an Array
In this guide, you will learn how to count the composite numbers in an array using Java. A composite is an integer greater than 1 that is not prime, and the problem is a tidy inversion of the “count primes” method with one important twist in the definition.
We will walk through the problem, build a complete program with an O(sqrt(n)) helper, trace it on a sample input, and then look at the “composite is not just non-prime” trap, the i * i overflow fix, and the follow-up questions a Java interviewer tends to ask on this problem.
Understanding the Problem
Given an array of n integers, the task is to return how many of them are composite. A composite integer is strictly greater than 1 and has at least one divisor other than 1 and itself. The smallest composite is 4, and 9 is the smallest odd composite.
The subtle part is that composite is not simply “not prime”. By convention, 0, 1, and every negative integer are neither prime nor composite. A naive !isPrime(n) implementation would wrongly count all three groups, so the helper has to reject anything below 4 up front.
Approach / Algorithm Steps
- Reject the input early if the array is
null. An empty array is fine: its count is0. - Declare a counter
countinitialised to0. - Walk the array and call a helper
isComposite(value)on each element, incrementingcountwhen the helper returnstrue. - Inside
isComposite, returnfalseimmediately for any value less than4. This single guard covers negatives,0,1,2, and3in one check, which handles the “neither prime nor composite” group and the two smallest primes together. - Return
truefor any even value from4onward, since the only even prime is2and it is already handled by the earlier guard. - Test odd divisors from
3up tosqrt(n)inclusive. The first hit meansnis composite; surviving the loop with no hit meansnis prime, so returnfalse. - Widen
i * itolongbefore comparing againstn. A plainintmultiplication overflows forinear46341, which is reachable whennis close toInteger.MAX_VALUE.
Java Program
public class CountComposites {
public static int countComposites(int[] numbers) {
if (numbers == null) {
throw new IllegalArgumentException("Array must not be null");
}
int count = 0;
for (int value : numbers) {
if (isComposite(value)) {
count++;
}
}
return count;
}
private static boolean isComposite(int n) {
if (n < 4) {
return false;
}
if (n % 2 == 0) {
return true;
}
for (int i = 3; (long) i * i <= n; i += 2) {
if (n % i == 0) {
return true;
}
}
return false;
}
public static void main(String[] args) {
int[] values = {2, 4, 7, 9, 10, 11, 15};
int composites = countComposites(values);
System.out.println("Composite count: " + composites);
}
}Explanation of the Program
The class CountComposites exposes a public countComposites method for the outer loop and a private isComposite helper for the per-element test. Separating the two concerns makes the main loop a two-line read and keeps the compositeness rules in one place.
The outer method validates against null, iterates with an enhanced for loop, and increments the counter when the helper says the current value is composite. The empty array is accepted and returns 0, which is the honest count for a dataset of size zero.
Inside isComposite, the first guard n < 4 rejects everything below the smallest composite. That single check covers five groups: all negatives, 0, 1, 2, and 3. Grouping them together is cleaner than four separate guards, and it reflects the mathematical convention that only integers greater than 1 can be composite.
The next check, n % 2 == 0, returns true immediately. Any even value of 4 or greater is divisible by 2 on top of 1 and itself, so it is composite by definition. Having the even case handled up front lets the main loop skip even divisors.
The main loop tests only odd divisors starting at 3 and incrementing by 2. Any composite n has at least one factor at most sqrt(n), so the loop stops once i * i exceeds n. Finding any divisor returns true; exhausting the loop without a hit returns false. Compared with the symmetric isPrime helper, both return paths are flipped.
The subtle part of the loop is the condition (long) i * i <= n. For n near Integer.MAX_VALUE, the loop variable i climbs past 46340, and 46341 * 46341 in plain int arithmetic overflows to a negative value. The (long) cast on i promotes the multiplication to long, which has enough headroom and keeps the comparison honest.
The main method is a tiny driver: it builds a mix of primes, composites, and the boundary values 2 and 7, calls countComposites, and prints the result. Running it prints Composite count: 4, which matches the composites 4, 9, 10, and 15 in the input.
Step-by-Step Trace
Let us trace countComposites on the input [1, 4, 6, 7, 9, 2]. The expected final answer is 3, since the composites are 4, 6, and 9.
| Iteration | value | isComposite path | Composite? | count (before) | count (after) |
|---|---|---|---|---|---|
| 1 | 1 | n < 4 guard | no | 0 | 0 |
| 2 | 4 | 4 % 2 == 0 | yes | 0 | 1 |
| 3 | 6 | 6 % 2 == 0 | yes | 1 | 2 |
| 4 | 7 | i = 3 fails 3*3 > 7 | no | 2 | 2 |
| 5 | 9 | i = 3, 9 % 3 == 0 | yes | 2 | 3 |
| 6 | 2 | n < 4 guard | no | 3 | 3 |
At the end of iteration i, count holds the number of composites among numbers[0..i-1]. The trace exercises every branch of the helper: the small-value guard (1, 2), the even-divisibility fast path (4, 6), the odd-divisor hit (9), and the odd-divisor loop exiting without a factor (7, which is prime).
Examples
Example 1: Mixed primes and composites
A short block of consecutive integers so both isComposite branches are exercised.
int[] nums = {4, 5, 6, 7, 8, 9};
int composites = countComposites(nums);
System.out.println(composites);
// Composites: 4, 6, 8, 9
// Output: 4Example 2: Non-positive values, 1, and small primes
Nothing in this input is composite: negatives, 0, and 1 are rejected by the first guard, and the two primes 2 and 3 are rejected by the same guard because they are below 4.
int[] nums = {-5, 0, 1, 2, 3, 5};
int composites = countComposites(nums);
System.out.println(composites);
// Output: 0Example 3: All composites
Every value is composite, so the count equals the array length. The odd composites 9 and 15 are caught by the odd-divisor loop; the even ones go through the fast path.
int[] nums = {4, 6, 8, 9, 10, 15};
int composites = countComposites(nums);
System.out.println(composites);
// Output: 6Common Mistakes to Avoid
The algorithm is short, but the definition of “composite” and the inverted return paths together produce several reliable traps. These are the mistakes learners actually make on this problem.
- Returning
!isPrime(n)– looks right, butisPrimereturnsfalsefor0,1, and every negative, so the negation counts all of those as composite. That silently inflates the result on any array with non-positive values. Keep a dedicatedisCompositehelper with its ownn < 4guard. - Treating
1as composite – by mathematical convention,1is neither prime nor composite, so a method that counts it is wrong. Then < 4guard covers this case for free. - Treating
0or negatives as composite – compositeness is defined only for integers greater than1. Letting any non-positive slip through makes every downstream statistic wrong. i * ioverflow – fornclose toInteger.MAX_VALUE, the loop variable grows past46340and46341 * 46341wraps to a negativeint. The loop then exits early or runs effectively forever depending on which side of zero the wrap lands on. Use(long) i * i.- Returning
falseon the first odd value – placing thefalsereturn inside theifbody instead of after the loop exits the method as soon as any odd non-divisor is encountered, so odd primes come back astrueand get counted as composite. Thereturn false;belongs after the loop.
Edge Cases to Test
Walk through this checklist before you call the solution done. The first few are the ones an interviewer is most likely to probe.
- Empty array (count is
0) - Null array reference
- Array containing only
0and1(neither is composite) - Array of only small primes
[2, 3, 5, 7](none composite) - Array containing
4(the smallest composite) - Array containing
9,25,49(smallest odd composites, hit by the odd-divisor loop) Integer.MAX_VALUEpresent (prime M31, not composite)Integer.MAX_VALUE - 2present (composite:5 * 429496729)
Additional Considerations
The per-element compositeness test runs in O(sqrt(n)) time with O(1) extra space. For an array of length m whose largest value is n, the whole method is bounded by O(m * sqrt(n)), which is already fast enough for arrays of a few thousand values with entries up to Integer.MAX_VALUE.
If the array contains many values and the maximum value N is bounded, the Sieve of Eratosthenes is the right tool. Build a boolean[N + 1] once in O(N log log N) time with true at index i meaning “i is composite”, then each query becomes an O(1) array lookup. Remember that the sieve indices 0, 1, and every negative query still need the “neither prime nor composite” guard, since the sieve itself does not represent that distinction.
The pair Integer.MAX_VALUE and Integer.MAX_VALUE - 2 on the edge-case list is a useful final sanity check. The value 2147483647 is the Mersenne prime 2^31 - 1, so a correct implementation must count it as not composite; the value 2147483645 is 5 * 429496729, so it must be counted as composite. A loop that overflows i * i typically breaks the second case silently.
Interview Follow-up Questions
The base problem is only the opening move. A real interviewer will push with questions like these, each probing a different axis of the solution.
- How would you count composites up to
Nrather than inside a specific array? – run a Sieve of Eratosthenes in O(N log log N), then count every indexiin4..Nwhose sieve entry is marked composite. - How would you speed up counting composites in a very long array when the maximum value is small? – precompute a sieve up to the maximum, then replace the per-element
isCompositecall with a single lookup. The method becomes O(N log log N + m). - How would you count semiprimes (composites that are the product of exactly two primes) inside the array? – factorise each candidate up to
sqrt(n), keep only the ones with exactly two prime factors counted with multiplicity (so4 = 2 * 2and15 = 3 * 5both qualify). - How would you count composites with exactly
kprime factors (counted with multiplicity)? – the same factorisation extended to track the big-omega count; a sieve of smallest prime factors makes the per-element work closer to O(log n). - How would you count composites in a very large array in parallel? – use
Arrays.stream(numbers).parallel().filter(CountComposites::isComposite).count(), which splits the array into chunks, counts each chunk independently, and sums the chunk counts.
Conclusion
Counting the composite numbers in an array in Java is an outer one-pass loop built around an O(sqrt(n)) helper, with three decisions tucked inside the helper: reject every value below 4 up front (because negatives, 0, 1, 2, and 3 are not composite), return true for every even value from 4 onward, and widen i * i to long so the loop condition stays correct for n near Integer.MAX_VALUE. Once those three habits are in place, the same shape of code extends cleanly to sieves, semiprime counting, and parallel reduce at scale.
Try adapting the code above to replace the per-element helper with a precomputed Sieve of Eratosthenes bounded by the array’s maximum value, keeping the n < 4 guard in place so 0, 1, and negatives are still excluded. The sieve wins once the array is longer than roughly the square root of the maximum.
You can learn more Array problems like this one here: Arrays.



