Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Skipping numbers in a for loop in Java. How can I make this more clean?

I need to create a for loop starting at 305 and ending at 397.

for (int i = 305; i < 397; i++) {
    //do stuff
}

The problem is, I need to skip 310, 321, 332, 343, 354, 365, 376, and 387.

I know I can do this by placing the following in the loop:

int[] skip = { 310, 321, 332, 343, 354, 365, 376, 387 };
for (int i2 : skip) {
    if (i != i2) {
        //do stuff
    }
}

But I feel like there is a much more efficient, clean way to achieve this.

like image 568
David Avatar asked Nov 29 '22 22:11

David


2 Answers

You can also simply add if (i % 11 == 2) continue; at the start of the loop:

for (int i = 305; i < 397; i++) {
  if (i % 11 == 2) continue;
  //do stuff
}

This is because you want to skip a number every 11 steps, starting at 310. So, you want to skip numbers for which i - 310 is a multiple of 11, so for which i - 310 + 11*X is a multiple of 11 whatever X is. So, I've chosen 28 for X, because i - 310 + 11 * 28 equals i - 2. This is easier to read. Finally, the test is simply (i - 2) % 11 == 0, and is equivalent to i % 11 == 2. This method of calculus is named basic modular arithmetic.

like image 85
Alexandre Fenyo Avatar answered Dec 05 '22 03:12

Alexandre Fenyo


If you're on java 8, You can use the new streams api with IntStream. You should also use a Set to check for membership quickly. Sets.newHashSet is a helper from guava, but you can also just create a HashSet by hand.

Set<int> intsToSkip = Sets.newHashSet( 310, 321, 332, 343, 354, 365, 376, 387 );
IntStream.range(305, 397)
    .filter(i => ! intsToSkip.contains(i))
    .forEach(i => {
        // do stuff
    })
like image 31
Alejandro C. Avatar answered Dec 05 '22 01:12

Alejandro C.