Optimization of a "Sieve of Eratosthenes" in Java
Alright, a few notes:

Your for loop strikes one as odd.


 for (int i = 0; i &lt; 1000; i++) {
                primes.add(i + 1);
            }



Why not start iteration at 1 and have your conditional be  &lt;= 1000, and you could just call primes.add(i) Note that this is just an example to be equivalent to yours, just removing unnecessary bloat, it actually makes the most sense to start with 2 for a sieve, since it's the first prime. These changes would more clearly communicate your intention.

Courtesy of this answer I learned that a sieve is best implemented through a simple boolean array.


  boolean[] sieve = new boolean[1000];
    Arrays.fill(sieve, true);

 for (int prime = 2; prime &lt; sieve.length; prime++) {
        if (sieve[prime]) {
            // this is a prime number
          for (int notPrime = prime * 2; notPrime &lt; sieve.length; notPrime += prime) {
              sieve[notPrime] = false;
          }
        }
    }



As this answer notes there may be ways to improve it, but I like this implementation for being light on memory (booleans are 1 bit) and the performance and convenience of simply using the indexes as the prime or not prime values.

Edit: Although booleans actually take up 1 bit in memory, the actual number of bits allocated is JVM dependent and typically a byte is reserved for each boolean used. Although the performance would be intangible using a Bitset would be the target route to achieve 1 bit per boolean.

*If any of this was useful, please give the linked answer up-vote priority.