For Loop Java Tutorial

by Dimitris Tasios
558 views

1. What is a for loop?

In this tutorial, we will learn about a fundamental feature of programming languages, as well as Java, for loops. If you want to repeat a block of code a fixed number of times, then a for loop in Java is all you need.

2. Why should I use a for loop in Java?

Imagine this scenario. You have a large array of numbers and you want to print a message on the screen for each element of the array. Without a for loop, you would have to add a System.out.println() statement for each element of the array. For example:

public class ExampleNoLoops {
    public static void main(String[] args) {

        // Declare our integer array with 10 elements
        int[] myNumbers = {2, 44, 5, 0, -3 ,33, 11, 1, 2, 776};

        // For every element, print its position and value. If this looks too much, imagine if you had 100 values...
        System.out.println("My position is " + 0 + " and my number is " + myNumbers[0]);
        System.out.println("My position is " + 1 + " and my number is " + myNumbers[1]);
        System.out.println("My position is " + 2 + " and my number is " + myNumbers[2]);
        System.out.println("My position is " + 3 + " and my number is " + myNumbers[3]);
        System.out.println("My position is " + 4 + " and my number is " + myNumbers[4]);
        System.out.println("My position is " + 5 + " and my number is " + myNumbers[5]);
        System.out.println("My position is " + 6 + " and my number is " + myNumbers[6]);
        System.out.println("My position is " + 7 + " and my number is " + myNumbers[7]);
        System.out.println("My position is " + 8 + " and my number is " + myNumbers[8]);
        System.out.println("My position is " + 9 + " and my number is " + myNumbers[9]);
    }
}

Output

My position is 0 and my number is 2
My position is 1 and my number is 44
My position is 2 and my number is 5
My position is 3 and my number is 0
My position is 4 and my number is -3
My position is 5 and my number is 33
My position is 6 and my number is 11
My position is 7 and my number is 1
My position is 8 and my number is 2
My position is 9 and my number is 776

As you can see, the code above is overwhelming and prone to errors. Imagine what could happen if you had 100 values and there was a spelling error in the 56th element which printed the number of the 66th. As a result, you would have to go through all of this wall of text, just to find that small spelling error.

A code like this can be avoided, by using a for loop, since it does all the hard work for you.

3. How to write a for loop in Java?

The basic syntax of a for loop is the following, which consists of 4 basic elements:

    for(starting expression; condition to check; increment/decrement) {
        statement(s)
    }
  1. Starting Expression: By using this expression, you declare where the loop should begin. For instance, in arrays the starting expression can be the first or the last element of the array.
  2. Condition to check: With this expression, you define when the loop should stop. If this condition is never met, the loop will be running, until it runs out of memory.
  3. Increment/decrement: Here, you declare how to progress the loop. In other words, you define the steps to take in order to be one step closer to the Condition to check.
  4. Statement(s): In this block, you are telling the loop what to do. You can place any actions that you want to perform repeatedly.

In order to demonstrate all this, let’s use the example above.

public class ExampleWithLoops {
    public static void main(String[] args) {

        // Declare our integer array with 10 elements
        int[] myNumbers = {2, 44, 5, 0, -3 ,33, 11, 1, 2, 776};

        /* For every element, print its position and value, using a for loop.
            * Starting expression: i = 0, or the first index of our array
            * Condition to check: as long as the i is less than the length of the array
            * Increment: move to the next element
            * Statement: print our message
        * */
        for(int i = 0; i < myNumbers.length; i++) {
            System.out.println("My position is " + i + " and my number is " + myNumbers[i]);
        }
    }
}

The output is the same as above, but the code is reduced drastically.

My position is 0 and my number is 2
My position is 1 and my number is 44
My position is 2 and my number is 5
My position is 3 and my number is 0
My position is 4 and my number is -3
My position is 5 and my number is 33
My position is 6 and my number is 11
My position is 7 and my number is 1
My position is 8 and my number is 2
My position is 9 and my number is 776

By using a for loop, we are now able to print the same message as many times as we want. In addition, we can be sure that there will not be any spelling mistakes, like the one mentioned in section 2, because we have let the loop handle the printing and the indices of each element.

3.1 An example without using arrays

Let’s see another example that does not use arrays. For example, we might need to print n random numbers. Alternatively, if we wanted to add all numbers from 0 to n and print the result, we could make a method like:

public class ExampleDynamicAdditionLoop {
    public static void main(String[] args) {
        System.out.println("Let's sum from 0 to 10");
        sumAndPrint(10);

        System.out.println("\nNow let's sum from 0 to 42");
        sumAndPrint(42);

        System.out.println("\nNow let's count to 42");
        reverseAddAndPrint(42);
    }

    // This method sums all numbers from 0 to our specified non-negative number and prints the result
    public static void sumAndPrint(int toNumber) {
        int result = 0;

        /* As you can see, the starting position can be whatever we want. There is no need to start from 0,
        because the first statement would be result = 0 + 0, which is unnecessary.
            * Starting expression: i = 1
            * Condition to check: as long as the i is less than our specified number
            * Increment: move to the next number
            * Statement: add current number to the result
         */
        for(int i = 1; i <= toNumber; i++) {
            result += i;
        }
        System.out.println("The sum from 0 to " + toNumber + " is " + result);
    }

    // This method sums all numbers from our specified negative number to 0 and prints the result
    public static void reverseAddAndPrint(int toNumber) {
        int result = 0;

        /* Here, we do the reverse process. We begin from our number and add the numbers in reverse. The result is the
        same as the above.
            * Starting expression: we start from our number
            * Condition to check: as long as the i is more than 0
            * Decrement: move to the next number, in reverse order
            * Statement: add current number to the result
         */
        for(int i = toNumber; i > 0; i--) {
            result += i;
        }
        System.out.println("The reverse sum from " + toNumber + " to 0 is " + result);
    }
}

Output

Let's sum from 0 to 10
The sum from 0 to 10 is 55

Now let's sum from 0 to 42
The sum from 0 to 42 is 903

Now let's count to 42
The reverse sum from 42 to 0 is 903

Our sumAndPrint(int toNumber) method takes a parameter and prints the sum of all numbers starting from 0 up to that number. As you can see in our main method, we can call sumAndPrint with a different parameter each time, making the loop more dynamic.

In the example above, you can also see a different approach to the for loop that goes backward. The method reverseAddAndPrint(int toNumber) begins the sum from the targeted number and moves back, adding the numbers in reverse order. The result is the same as the sumAndPrint method.

3.2 A bidirectional example

So far we have discussed going either forwards or backward in a loop. What if we wanted to go in both directions, would that be possible? The answer to this question is yes, it is indeed possible.

Let’s assume that we want to check whether a word is a palindrome. A palindrome word reads the same forward and backward. In that case, the loop would be a bit trickier, as shown below:

public class ExampleBidirectionalLoop {
    public static void main(String[] args) {
        checkPalindrome("anna"); // even length
        checkPalindrome("john");
        checkPalindrome("aba"); // odd length
        checkPalindrome("abc");
        checkPalindrome("d"); // single letter is palindrome to itself
        checkPalindrome("Pop"); // capitalization matters in our example. You can make it ignore cases

    }

    /* This method checks and prints whether a string is palindrome.
       A palindrome word reads the same backward as forward. */
    public static void checkPalindrome(String word) {

        // Because of the symmetry of palindrome words, we only need to check until the middle of the word
        int mid = word.length() / 2;

        /* The loop's expressions are a bit trickier here.
             * Starting expression: i = 0 for the beginning of the word, j = word.length() - 1 for the ending of the word.
             *                      Remember, indices are zero-indexed.
             * Condition to check: i must be on the first half of the word, j on the second half
             * Increment/decrement: i moves towards the middle in proper order, j in reverse order
             * Statement: explained below
        */

        for(int i = 0, j = word.length() - 1; i <= mid && j >= mid; i++, j--) {

            // If the characters in symmetrical places are different, then the word is not palindrome
            if(word.charAt(i) != word.charAt(j)) {
                System.out.println(word + " is not a palindrome");
                return; // Used to stop the loop, as well as the function
            }
        }

        // Nothing stopped us, so the word is palindrome
        System.out.println(word + " is a palindrome");
    }
}

In more detail, for each loop element we have the following:

  1. Starting expression: In order to check the word for being a palindrome, we have to be looking at both directions during the loop. So, to do that, we have one index, i, that starts from the beginning of the word and another index j, that starts from the end.
  2. Condition to check: Both indices will stop when they meet in the middle of the word (we are taking advantage of the symmetry of palindromes).
  3. Increment/decrement: Index i moves forward towards the middle, j moves backward.
  4. Statements: We are checking the characters at each place. If they are different, it means that the word is not a palindrome. If this check never applies, the loop completes, meaning that the word is a palindrome.

Output

anna is a palindrome
john is not a palindrome
aba is a palindrome
abc is not a palindrome
d is a palindrome
Pop is not a palindrome

Note that in order to exit from the loop, we used the return keyword. This is explained in the following subsection.

3.3 Interrupting loops

In our Bidirectional example, we wanted to exit the loop once we found out that the word is not a palindrome, and we did that with the return keyword.

There are multiple different ways to exit a loop prematurely, by using one of the following keywords:

  • break: Used to break from the current loop and move on to the statements after the loop
  • continue: Ignore the rest of the statements in the current iteration and move on the next one, without exiting.
  • return: Exit the loop and do not move any further into the method.

Let’s see an example. In all cases, we are iterating from 0 through 9, but when we reach the number 5, we perform a different action. As a result, the flow of the executions alters between the three methods.

public class ExampleInterruptingLoops {
    public static void main(String[] args) {
        breakLoop();
        System.out.println("-------------------------------------------");
        continueLoop();
        System.out.println("-------------------------------------------");
        returnLoop();
    }

    /* When breaking a loop, no other statements in the loop will be executed*/
    public static void breakLoop() {
        for(int i = 0; i < 10; i++) {
            if(i == 5) {
                System.out.println("breakLoop: Breaking the loop");
                break;
            }
            System.out.println("breakLoop: My number is " + i);
        }
        System.out.println("breakLoop: I will be executed after loop ends!");
    }

    // When continuing a loop, the statements of the loop's current iteration will not be executed
    public static void continueLoop() {
        for(int i = 0; i < 10; i++) {
            if(i == 5) {
                System.out.println("continueLoop: Continuing the loop, I hate number 5...");
                continue;
            }
            System.out.println("continueLoop: My number is " + i);
        }
        System.out.println("continueLoop: I will be executed after loop ends!");
    }

    // When returning in a loop, execution of the methods stops at that point. 
    public static void returnLoop() {
        for(int i = 0; i < 10; i++) {
            if(i == 5) {
                System.out.println("returnLoop: Number 5? Time to leave...");
                return; // if the method returns a type (e.g. int), we have to return a value of the type (e.g return -1;)
            }
            System.out.println("returnLoop: My number is " + i);
        }
        System.out.println("returnLoop: I hope will be executed after loop ends...");
    }
}

Output

breakLoop: My number is 0
breakLoop: My number is 1
breakLoop: My number is 2
breakLoop: My number is 3
breakLoop: My number is 4
breakLoop: Breaking the loop
breakLoop: I will be executed after loop ends!
-------------------------------------------
continueLoop: My number is 0
continueLoop: My number is 1
continueLoop: My number is 2
continueLoop: My number is 3
continueLoop: My number is 4
continueLoop: Continuing the loop, I hate number 5...
continueLoop: My number is 6
continueLoop: My number is 7
continueLoop: My number is 8
continueLoop: My number is 9
continueLoop: I will be executed after loop ends!
-------------------------------------------
returnLoop: My number is 0
returnLoop: My number is 1
returnLoop: My number is 2
returnLoop: My number is 3
returnLoop: My number is 4
returnLoop: Number 5? Time to leave...

As you can notice, break causes the loop to stop, but the code afterward is executed, continue simply skips the current iteration and return stops execution at the point the keyword appears.

4. A special for loop for arrays, the enhanced for loop

If you are using arrays, there is another type of for loop that we can use, the enhanced for loop, also known as “for-each” loop. In contrast to the normal for loop, which is focused on indices, an enhanced for loop is focused on the elements of the array. As a result, the syntax of an enhanced for loop is much simpler, as shown below:

for (arrayType nameOfVariable : nameOfArray) {
  statement(s)
}

In more detail:

  1. arrayType: The type of the array or, more correctly, an element of the array.
  2. nameOfVariable: The name of the current element of the array.
  3. nameOfArray: The name of the array
  4. statement(s): Just like in the regular for loop.

By using enhanced for loops, we can rewrite the numbers array example from section 3, like such:

public class ExampleEnhancedLoop {
    public static void main(String[] args) {

        // Declare our integer array with 10 elements
        int[] myNumbers = {2, 44, 5, 0, -3 ,33, 11, 1, 2, 776};

        /* Print every element in the array.
         * arrayType: int, type of elements in the array
         * nameOfVariable: number, naming the current element
         * nameOfArray: myNumbers, the array to iterate
         * Statement: print our message
         * */
        for(int number: myNumbers) {
            System.out.println("My number is " + number);
        }
    }
}

The first thing you might notice is that by using the enhanced for loop, we do not have access to the element’s index. So, it is not possible to know the position of the variable number in each iteration, when using enhanced for loops.

Output

My number is 2
My number is 44
My number is 5
My number is 0
My number is -3
My number is 33
My number is 11
My number is 1
My number is 2
My number is 776

5. Nested and labeled loops

It is possible to have loops within loops. If we would like to break or continue a specific loop in a group of nested loops, we can use a label. Labels help identify loops by giving them a name. By default, if there are multiple nested loops of which none have a label, break and continue apply to the innermost loop.

The example below demonstrates all of this. There are two methods with nested loops; one that uses labels and one that does not. The unlabeled nested loop is more limited when it comes to interrupting iterations, as it can only affect the innermost loop. On the contrary, the labeled nested loop has more flexibility in its flow, thanks to the labels.

public class ExampleLabeledNestedLoops {
    public static void main(String[] args) {
        nestedUnlabeledLoop();
        System.out.println("********************************************");
        nestedLabeledLoop();
    }

    /* When in an inner group, breaking/continuing affects the inner loop only*/
    public static void nestedUnlabeledLoop() {
        for(int i = 0; i < 5; i++) {
            for(int j = 0; j < 3; j++) {
                if(i == 1) {
                    System.out.println("nestedUnlabeledLoop: Skipping i = " + i);
                    break;
                }
                System.out.println("nestedUnlabeledLoop: "+ i + " " + j);
            }
            System.out.println("-----");
        }
        System.out.println("nestedUnlabeledLoop: Loops are finished!");
    }

    /* With labels, we can specify which loop to break/continue*/
    public static void nestedLabeledLoop() {
       outerLoop: for(int i = 0; i < 10; i++) {
           innerLoop: for(int j = 0; j < 3; j++) {
                if(i == 1) {
                    System.out.println("nestedLabeledLoop: Skipping unlabeled i = " + i);
                    break;
                }
               if(i == 4) {
                   System.out.println("nestedLabeledLoop: Skipping labeled i = " + i);
                   break innerLoop; // same as unlabeled case
               }
                if(i == 6) {
                    System.out.println("nestedLabeledLoop: Exitting at i = " + i);
                    break outerLoop;
                }
                System.out.println("nestedLabeledLoop: " + i + " " + j);
            }
            System.out.println("-----");
        }
        System.out.println("nestedLabeledLoop: Loops are finished!");
    }
}

The output should make everything more clear. Notice that in nestedLabeledLoop method, the use of the innermost’s loop label is optional.

nestedUnlabeledLoop: 0 0
nestedUnlabeledLoop: 0 1
nestedUnlabeledLoop: 0 2
-----
nestedUnlabeledLoop: Skipping i = 1
-----
nestedUnlabeledLoop: 2 0
nestedUnlabeledLoop: 2 1
nestedUnlabeledLoop: 2 2
-----
nestedUnlabeledLoop: 3 0
nestedUnlabeledLoop: 3 1
nestedUnlabeledLoop: 3 2
-----
nestedUnlabeledLoop: 4 0
nestedUnlabeledLoop: 4 1
nestedUnlabeledLoop: 4 2
-----
nestedUnlabeledLoop: Loops are finished!
********************************************
nestedLabeledLoop: 0 0
nestedLabeledLoop: 0 1
nestedLabeledLoop: 0 2
-----
nestedLabeledLoop: Skipping unlabeled i = 1
-----
nestedLabeledLoop: 2 0
nestedLabeledLoop: 2 1
nestedLabeledLoop: 2 2
-----
nestedLabeledLoop: 3 0
nestedLabeledLoop: 3 1
nestedLabeledLoop: 3 2
-----
nestedLabeledLoop: Skipping labeled i = 4
-----
nestedLabeledLoop: 5 0
nestedLabeledLoop: 5 1
nestedLabeledLoop: 5 2
-----
nestedLabeledLoop: Exitting at i = 6
nestedLabeledLoop: Loops are finished!

6. Infinite loops

Infinite loops can be achieved in a for loop, in addition to while and do-while loops. An infinite loop is one that runs indefinitely, until a condition inside it interrupts it, with the help of the break, continue and return keywords.

The syntax of an infinite for loop is similar to a regular for loop, but without any expression in the parenthesis, except for two semicolons:

for(;;) {
  statement(s)
}

The example below has two methods, one whose loop can be interrupted, infiniteLoopThatStops(), and one whose loop cannot, infiniteLoopThatNeverStops().

The first method keeps generating a random number until it is smaller than 0.01, so in that case, the number and the number of iterations are printed. The second method keeps adding numbers to a dynamic ArrayList (which can also be used in loops) until it runs out of memory. When it does, we catch that error and print the approximate seconds it took for it to occur.

import java.util.ArrayList;

public class ExampleInfiniteLoops {
    public static void main(String[] args) {
        infiniteLoopThatStops();
        System.out.println();
        infiniteLoopThatNeverStops();
    }

    public static void infiniteLoopThatStops() {
        int iterations = 0;
        double randomNumber = 0.0;
        for (;;) {
            
            // generate a random number
            randomNumber = Math.random();
            
            // increase iterations by 1
            iterations++;
            
            // exit infinite loop if the random number is less than 0.01
            if(randomNumber < 0.01) {
                break;
            }
        }
        
        // print the number and iterations it took to get that number
        System.out.println("Number is : " + randomNumber+ " Iterations : " + iterations);
    }

    public static void infiniteLoopThatNeverStops() {
        
        // create a dynamic ArrayList
        ArrayList<Double> arrayList = new ArrayList<Double>();
        
        // keep note of the current time
        long timestampStart = System.nanoTime();

        // a try block is used to catch the eventual OutOfMemoryError and perform the wanted actions
        try {
            for (;;) {
                double randomNumber = Math.random();
                
                // append the random number to the list. It doesn't matter if it's random
                arrayList.add(randomNumber);
            }
        } catch(OutOfMemoryError error) {
            // print stack trace of the error, as well as the time it took for it to happen (in seconds)
            error.printStackTrace();
            long timestampFinish = System.nanoTime();
            System.out.println("Time elapsed until OutOfMemoryError: "+ (timestampFinish - timestampStart)/1000000000);
        }
    }
}

If you run the above code, you most probably will get a slightly different output, because of the random numbers in the first method and the memory availability in the second method.

Number is : 0.004914335500236011 Iterations : 176

java.lang.OutOfMemoryError: Java heap space
	at java.base/java.util.Arrays.copyOf(Arrays.java:3511)
	at java.base/java.util.Arrays.copyOf(Arrays.java:3480)
	at java.base/java.util.ArrayList.grow(ArrayList.java:237)
	at java.base/java.util.ArrayList.grow(ArrayList.java:244)
	at java.base/java.util.ArrayList.add(ArrayList.java:454)
	at java.base/java.util.ArrayList.add(ArrayList.java:467)
	at ExampleInfiniteLoops.infiniteLoopThatNeverStops(ExampleInfiniteLoops.java:29)
	at ExampleInfiniteLoops.main(ExampleInfiniteLoops.java:6)
Time elapsed until OutOfMemoryError: 11

7. Conclusion

Those were the basics of Java’s for loop. You can find the source code on our GitHub page.

8. Sources

[1]: The for Statement – Oracle

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

Related Posts