Sieve of Eratosthenes Primes Efficiency
Your code is mostly right. primeCounter is a misleadingly named variable, since it counts non-primes. And, similarly, primes isn't an array of primes, but rather an array of flags indicating prime-ness. It would be better to name this one isPrime.

There is an Arrays.fill method that you may want to use for clarity:

Arrays.fill(isPrime, true);


And it may be easier to simply add the primes as you go though, and return an ArrayList&lt;int&gt;:

/* 
 * Calculate primes up to num using Sieve of Eratosthenes algorithm
 */
ArrayList&lt;int&gt; primes = new ArrayList&lt;int&gt;();
for (int i = 2; i &lt;= num; i++) {
    if (isPrime[i]) {
        primes.add(i);
        for (int k = i * i; k &lt;= num; k += i) {
            isPrime[k] = false;
        }
    }
}
return primes;


The other advantage of ArrayList is that you don't have to have a separate index to keep track of where in your array you're inserting into - let the container do its job!