I am making a program to find primes between the given range of numbers. Unfortunately, the algorithm I created is too slow. Do you have any ideas of how to optimize the code?
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args)throws IOException {
Scanner s = new Scanner(System.in);
int numberOfTests;
int l, n;
numberOfTests = s.nextInt();
for (int q = 0; q < numberOfTests; q++) {
l = s.nextInt();
n = s.nextInt();
if (l==1)l++;
BitSet primeBitSet = new BitSet((int) (Math.sqrt(n) + 1));
ArrayList <Integer> primeTable = new ArrayList <Integer>((int) Math.sqrt(n));
if (l < 1 || n < 1 || l > n || n > 1000000000) {
System.exit(0);
}
//classic sieve from 1 to sqrt(n)
for (int j = 2; j * j <= n; j++) {
if (primeBitSet.get(j - 1) == true) {
continue;
} else {
primeTable.add(j);
for (int k = 2 * j; k <= n; k += j) {
primeBitSet.set(k - 1);
}
}
}
//sieve in the expected range using primes generated by the classic sieve
BitSet primesInRangeBitSet = new BitSet(n - l + 1);
int pomoc;
for (int i = 0; i < primeTable.size(); ++i) {
pomoc = l / ((int) primeTable.get(i));
pomoc = pomoc * ((int) primeTable.get(i));
for (int j = pomoc; j <= n; j = j + (int) primeTable.get(i)) {
if (j < l || primesInRangeBitSet.get(j - l) == true ) {
continue;
} else {
primesInRangeBitSet.set(j - l);
}
}
}
//outputting the primes
for (int k = 0; k < primeTable.size(); k++){
if((int)primeTable.get(k)>= l &&(int) primeTable.get(k) <= n)
System.out.println(primeTable.get(k));
}
for (int k = 0; k < primesInRangeBitSet.size(); k++) {
if (primesInRangeBitSet.get(k) == false && k <= n - l ) {
System.out.println((k + l));
}
}
System.out.println("");
}
}
}