Loops in Java – Ultimate Guide

In this tutorial, we’ll cover the four types of loops in Java: the for loop, enhanced for loop (for-each), while loop and do-while loop. We’ll also cover loop control flow concepts with nested loops, labeled loops, break statement, continue statement, return statement and local variable scope. We’re also going to cover common loop exceptions and errors like infinite loops, java.lang.ArrayIndexOutOfBoundsException and java.lang.OutOfMemoryError.

Each type of loop will be shown with multiple examples so you can see how it’s used in a wide variety of circumstances. We’ll cover how you loop over characters in a string, an array of strings, an array of integers, as well as iterating over collections such as java.util.List, java.util.Set and java.util.Map.

Introduction

Loops are used in most programs for a variety of reasons. The basic reason for using loops is when a repetitive action needs to be taken over and over. Usually, this will be for a set of data. It’s better and more efficient to use loops than having to explicitly write the code to process each action. And sometimes the programmer won’t know in advance how many pieces of data the program will encounter so looping will be necessary.

For example, loops can be used to iterate over a list of returned database records, to sort a list of numbers, or to read a file line by line.

Loops Concepts

All loops in Java use the same building blocks that we’re going to define here.

  • loop initialization – setting the initial value of variable(s) to be used in the loop
  • boolean condition – this is a boolean expression that determines whether to continue looping for one more iteration
  • step value (update value) – an update to the loop variable(s)
  • loop body – execute the main part of the loop that does the processing

Throughout this tutorial, we’ll be referring to these concepts as we introduce each loop.

For Loop

For loops are best used when you know how many times you have to loop over something. For example, when looping over an array of numbers you will need to loop over as many times as there are elements in the array.

For Loop Structure

Java for loops are structured to follow this order of execution:

1) loop initialization
2) boolean condition – if true, continue to next step; if false, exit loop
3) loop body
4) step value
5) repeat from step 2 (boolean condition)

java-for-loop-diagram

Example – Incrementing Step Value

Here is a simple for loop incrementing values from 0 to 99.

Notice the settings for the loop:

  • loop index is initialized to 0
  • boolean condition tests that the loop index is less than 100
  • step value increments the loop index by 1 after every loop
  • loop exits when i gets to 100 and the boolean condition evaluates to false
1
2
3
    for(int i=0; i<100; i++) {
      System.out.println(i);
    }

Output:

1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
...
96
97
98
99

Example – Decrementing Step Value

Here is a similar for loop decrementing values from 100 to 1.

1
2
3
    for(int i=100; i>0; i--) {
      System.out.println(i);
    }

Notice that we changed the following:

  • loop is initialized at 100
  • boolean condition tests that the loop index is greater than 0
  • the step value decrements the loop index by 1 after every loop
  • loop exits when i gets to 0 and the boolean condition evaluates to false

Output:

1
2
3
4
5
6
7
8
9
100
99
98
97
...
4
3
2
1

Example – Multiple Loop Variables

You can also use more than one variable in the loop initialization, test expression and for the step value. The only limitation is that the boolean test expression has to evaluate to a single value (true or false). Here is an example using 3 different variables for the loop initialization, test condition and step value. Notice how the test condition only has one value, even though we’re using three variables.

1
2
3
    for(int i=0, j=5, k=30; (i+j+k)<500; i+=5, j*=2, k-= 2) {
      System.out.println(i+j+k);
    }

Output:

1
2
3
4
5
6
7
35
43
56
79
122
205
368

Example – No Initialization

Every part of the loop is optional. So you don’t have to have a loop initialization and step value, or even a test condition.

In the next example, we’re missing the loop initialization because we’re using a local variable that we initialized before the loop.

1
2
3
4
    int i=0;
    for(; i<5; i++) {
      System.out.println(i);
    }

Output:

1
2
3
4
5
0
1
2
3
4

Example – No Step Value

You also don’t need the step (update) value. In the following example, we removed it and we’re incrementing the loop index inside the loop body.

1
2
3
4
    int i=0;
    for(; i<5; ) {
      System.out.println(i++);
    }

Output:

1
2
3
4
5
0
1
2
3
4

Example – Infinite Loop

Finally, we can remove the boolean test condition but that will cause an infinite loop and the program will never terminate on its own.

1
2
3
4
    int i=0;
    for(; ; ) {
      System.out.println(i++);
    }

Output:

1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
... keeps growing without end

Example – Integer Array

To loop over an integer array with a for loop, we initialize the loop variable to 0, which is the first array index. The boolean expression tests to make sure that i is less than the size of the array because the last array index will be 1 less than the size of the array.

1
2
3
4
    int [] intArray = {1, 3, 5, 7, 9};
    for(int i=0; i<intArray.length; i++) {
      System.out.println(intArray[i]);
    }

Output:

1
2
3
4
5
1
3
5
7
9

Example – String Characters

To loop over a string of characters with a for loop, we initialize the loop variable to 0 and then use the String.charAt() method to get the character at the specified index. Just like in the integer array example, we’re starting the loop index at 0 and going up to 1 less the size of the string. This is because string indexes work in a similar way as arrays in Java: first character index is 0 and the last character index will be 1 less than the size of the string.

1
2
3
4
5
    String myString = "hello";
   
    for(int i=0; i<myString.length(); i++) {
      System.out.print(myString.charAt(i));
    }

Output:

1
hello

Example – String Array

To loop over an array of strings with a for loop, we’ll use a similar technique like we used to loop over an array of integers. The loop index is initialized to 0 and we keep looping until 1 less than the size of the string array.

1
2
3
4
5
6
7
8
9
10
    String [] myStrings  = {
        "alpha",
        "beta",
        "gamma",
        "delta"
      };
   
    for(int i=0; i<myStrings.length; i++) {
      System.out.println(myStrings[i]);
    }

Output:

1
2
3
4
alpha
beta
gamma
delta

Example – List

To loop over a java.util.List with a for loop, we initialize the loop variable to 0 and keep looping until 1 less than the size of the list. We use the List.get() method to retrieve the specific list element with the current loop index. The example uses a list of strings but the structure would work the same way for a list of other elements.

1
2
3
4
5
6
7
8
9
    List<String> myList = new ArrayList<String>();
    myList.add("alpha");
    myList.add("beta");
    myList.add("gamma");
    myList.add("delta");
   
    for(int i=0; i<myList.size(); i++) {
      System.out.println(myList.get(i));
    }

Output:

1
2
3
4
alpha
beta
gamma
delta

Example – Set 1

We can’t iterate over a java.util.Set directly with a for loop by accessing its elements with an index the way we did for a list. Instead, we need to convert the set into an array first and then iterate over the array. This is one way of converting a java.util.Set to an array. Notice that the converted array is a generic array of Objects even though the original set consisted of strings. After the conversion to the array, we iterate over it in a similar way as we did for an array of integers. Also notice that the set stored just the unique strings that we added and not in the order that we added them.

1
2
3
4
5
6
7
8
9
10
11
12
13
      Set<String> mySet = new HashSet<String>();
      mySet.add("alpha");
      mySet.add("alpha");
      mySet.add("beta");
      mySet.add("gamma");
      mySet.add("gamma");
      mySet.add("delta");
     
      Object [] mySetStrings = mySet.toArray();
     
      for(int i=0; i<mySetStrings.length; i++) {
        System.out.println(mySetStrings[i]);
      }

Note how the output is in a different order from the order we inserted elements into the set:

1
2
3
4
alpha
delta
beta
gamma

Example – Set 2

We can also use a for loop to iterate over a java.util.Set by converting it first to an array of the specific type. In this example, we’re iterating over the set’s elements in a for loop after they’ve been converted to an array of strings.

1
2
3
4
5
6
7
8
9
10
11
12
13
      Set<String> mySet = new HashSet<String>();
      mySet.add("alpha");
      mySet.add("alpha");
      mySet.add("beta");
      mySet.add("gamma");
      mySet.add("gamma");
      mySet.add("delta");
     
      String [] mySetStrings = mySet.toArray(new String[mySet.size()]);
     
      for(int i=0; i<mySetStrings.length; i++) {
        System.out.println(mySetStrings[i]);
      }

Note how the output is in a different order from the order we inserted elements into the set:

1
2
3
4
alpha
delta
beta
gamma

Example – Map

To iterate over a java.util.Map with a for loop, we first get the map’s set of keys and then convert that java.util.Set to a String array.

1
2
3
4
5
6
7
8
9
10
11
12
13
    Map <String,String>myMap = new HashMap<String,String>();
    myMap.put("a", "alpha");
    myMap.put("b", "beta");
    myMap.put("c", "gamma");
    myMap.put("d", "delta");

    Set<String> keySet = myMap.keySet();
   
    String [] keys = keySet.toArray(new String [keySet.size()]);

    for(int i=0; i<keys.length; i++) {
      System.out.println("Key:" + keys[i] + " Value:" + myMap.get(keys[i]));
    }

Output:

1
2
3
4
Key:a Value:alpha
Key:b Value:beta
Key:c Value:gamma
Key:d Value:delta

Further Reading

The for Statement (The Java™ Tutorials)
Java Programming Tutorial – 22 – for Loops (YouTube)
How to Iterate over a Set/HashSet without an Iterator?

Enhanced For Loop

Enhanced for loops (aka for-each or foreach loops) are a simplified version of a for loop. The advantage is that there is less code to write and less variables to manage. The downside is that you have no control over the step value and no access to the loop index inside the loop body.

They are best used when the step value is a simple increment of 1 and when you only need access to the current loop element. For example, if you need to loop over every element in an array or Collection without peeking ahead or behind the current element.

Enhanced For Loop Structure

Enhanced for loops follow this order of execution:

1) loop body
2) repeat from step 1 until entire array or collection has been traversed

There is no loop initialization, no boolean condition and the step value is implicit and is a simple increment. This is why they are considered so much simpler than regular for loops.

java-enhanced-for-loop-diagram

Example – Integer Array

You can use an enhanced for loop to traverse the elements of an int array one by one:

1
2
3
4
    int [] intArray = {1, 3, 5, 7, 9};
    for(int currentValue : intArray) {
      System.out.println(currentValue);
    }

The currentValue variable holds the current value being looped over in the intArray array. Notice there’s no explicit step value – it’s always an increment by 1.

The colon can be thought of to mean “in”. So the enhanced for loop declaration states: loop over intArray and store the current array int value in the currentValue variable.

The output is:

1
2
3
4
5
1
3
5
7
9

Example – String Characters

We can’t use the enhanced for loop to iterate directly over a single String. If you try to do that as in the following code, you will get a compile time error.

1
2
3
4
5
6
    String myString = "hello";
   
    //compile time error: Can only iterate over an array or an instance of java.lang.Iterable
    for(char c : myString) {
     
    }

Output:

1
2
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
  Can only iterate over an array or an instance of java.lang.Iterable

To solve this problem, we can convert the string to an array of characters and then iterate over the array:

1
2
3
4
5
    String myString = "hello";

    for(char c : myString.toCharArray()) {
      System.out.print(c);
    }

Output:

1
hello

Example – String Array

We can use the for-each loop to iterate over an array of strings. The loop declaration states: loop over myStrings String array and store the current String value in the currentString variable.

1
2
3
4
5
6
7
8
9
10
    String [] myStrings  = {
      "alpha",
      "beta",
      "gamma",
      "delta"
    };

    for(String currentString : myStrings) {
      System.out.println(currentString);
    }

Output:

1
2
3
4
alpha
beta
gamma
delta

Example – List

The enhanced for loop can also be used to iterate over a java.util.List as follows:

1
2
3
4
5
6
7
8
9
    List<String> myList = new ArrayList<String>();
    myList.add("alpha");
    myList.add("beta");
    myList.add("gamma");
    myList.add("delta");
   
    for(String currentItem : myList) {
      System.out.println(currentItem);
    }

The loop declaration states: loop over myList List of Strings and store the current List value in the currentItem variable.

Output:

1
2
3
4
alpha
beta
gamma
delta

Example – Set

The enhanced for loop can also be used to iterate over a java.util.Set as follows:

1
2
3
4
5
6
7
8
9
10
11
    Set<String> mySet = new HashSet<String>();
    mySet.add("alpha");
    mySet.add("alpha");
    mySet.add("beta");
    mySet.add("gamma");
    mySet.add("gamma");
    mySet.add("delta");
   
    for(String currentItem : mySet) {
      System.out.println(currentItem);
    }

The loop declaration states: loop over mySet Set of Strings and store the current Set value in the currentItem variable. Notice that since this is a Set, duplicate String values are not stored. Also, there’s no need to convert the Set elements into an array the way we had to do for a regular for loop.

Output:

1
2
3
4
alpha
delta
beta
gamma

Example – Map

To iterate over a java.util.Map with a for-each loop, we can iterate over the map’s set of keys:

1
2
3
4
5
6
7
8
9
10
11
    Map <String,String>myMap = new HashMap<String,String>();
    myMap.put("a", "alpha");
    myMap.put("b", "beta");
    myMap.put("c", "gamma");
    myMap.put("d", "delta");

    Set<String> keySet = myMap.keySet();
   
    for(String currentKey : keySet) {
      System.out.println("Key:" + currentKey + " Value:" + myMap.get(currentKey));
    }

Output:

1
2
3
4
Key:a Value:alpha
Key:b Value:beta
Key:c Value:gamma
Key:d Value:delta

Further Reading

For-Each Loop – Java 5 Documentation
What is the syntax of enhanced for loop in Java?
Java Programming Tutorial – 31 – Enhanced for Loop (YouTube)
Java for loop syntax: “for (T obj : objects)”

While Loop

While loops are best used when you don’t know how many times you have to loop over something. For example, when reading lines of text from a file, a program will keep reading until it gets to the end of the file, without knowing beforehand how many lines it will read.

While Loop Structure

While loops in Java have a simpler structure than for loops because they don’t have an initialization or a step value. Their structure follows this order of execution:

1) boolean condition – if true, continue to next step; if false, exit loop
2) loop body
3) repeat from step 1 (boolean condition)

java-while-loop-diagram

Example – Integer Array

To loop over an integer array with a while loop, we initialize a local variable to 0, which is the first array index. The boolean expression tests to make sure that i is less than the size of the array because the last array index will be 1 less than the size of the array. We also increment the local variable inside the loop body.

1
2
3
4
5
    int [] intArray = {1, 3, 5, 7, 9};
    int i=0;
    while(i<intArray.length) {
      System.out.println(intArray[i++]);
    }

Output:

1
2
3
4
5
1
3
5
7
9

Example – String Characters

To loop over a string of characters with a while loop, we initialize a local variable to 0 and then use the String.charAt() method to get the character at the specified index. As in the previous example, we increment the local variable inside the loop body.

1
2
3
4
5
6
    String myString = "hello";
   
    int i=0;
    while(i<myString.length()) {
      System.out.print(myString.charAt(i++));
    }

Output:

1
hello

Example – String Array

To loop over an array of strings with a while loop, we’ll use a similar technique like we used to loop over an array of integers. A local variable is initialized to 0 and we keep looping until 1 less than the size of the string array, while incrementing the local variable inside the loop body.

1
2
3
4
5
6
7
8
9
10
11
    String [] myStrings  = {
      "alpha",
      "beta",
      "gamma",
      "delta"
    };

    int i=0;
    while(i<myStrings.length) {
      System.out.println(myStrings[i++]);
    }

Output:

1
2
3
4
alpha
beta
gamma
delta

Example – List

To loop over a java.util.List with a while loop, we initialize a local variable to 0 to use it as the list index and keep looping until 1 less than the size of the list. We use the List.get() method to retrieve the specific list element with the local variable and increment it within the loop body.

1
2
3
4
5
6
7
8
9
10
    List<String> myList = new ArrayList<String>();
    myList.add("alpha");
    myList.add("beta");
    myList.add("gamma");
    myList.add("delta");

    int i=0;
    while(i<myList.size()) {
      System.out.println(myList.get(i++));
    }

Output:

1
2
3
4
alpha
beta
gamma
delta

Example – Set 1

We can’t iterate over a java.util.Set directly with a while loop by accessing its elements with an index the way we did for a list. Instead, we need to convert the set into an array first and then iterate over the array. The converted array is a generic array of Objects even though the original set consisted of strings. After the conversion to the array, we iterate over it in a similar way as we did for an array of integers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    Set<String> mySet = new HashSet<String>();
    mySet.add("alpha");
    mySet.add("alpha");
    mySet.add("beta");
    mySet.add("gamma");
    mySet.add("gamma");
    mySet.add("delta");

    Object [] mySetStrings = mySet.toArray();

    int i=0;
    while(i<mySetStrings.length) {
      System.out.println(mySetStrings[i++]);
    }

Output:

1
2
3
4
alpha
delta
beta
gamma

Example – Set 2

We can also use a while loop to iterate over a java.util.Set by converting it first to an array of the specific type. In this example, we’re iterating over the set’s elements in a while loop after they’ve been converted to an array of strings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Set<String> mySet = new HashSet<String>();
    mySet.add("alpha");
    mySet.add("alpha");
    mySet.add("beta");
    mySet.add("gamma");
    mySet.add("gamma");
    mySet.add("delta");

    String [] mySetStrings = mySet.toArray(new String[mySet.size()]);

    int i=0;
   
    while(i<mySetStrings.length) {
      System.out.println(mySetStrings[i++]);
    }

Output:

1
2
3
4
alpha
delta
beta
gamma

Example – Map

To iterate over a java.util.Map with a while loop, we first get the map’s set of keys and then convert that java.util.Set to a String array. Note how we have to manually increment i inside the loop body because we’re not using a for loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Map <String,String>myMap = new HashMap<String,String>();
    myMap.put("a", "alpha");
    myMap.put("b", "beta");
    myMap.put("c", "gamma");
    myMap.put("d", "delta");

    Set<String> keySet = myMap.keySet();

    String [] keys = keySet.toArray(new String [keySet.size()]);

    int i=0;
    while(i<keys.length) {
      System.out.println("Key:" + keys[i] + " Value:" + myMap.get(keys[i]));
      i++;
    }

Output:

1
2
3
4
Key:a Value:alpha
Key:b Value:beta
Key:c Value:gamma
Key:d Value:delta

Example – Infinite Loop

An infinite while loop will occur when the boolean condition is always true. This loop could still be broken out of if inside the loop body the break or return statement was used.

1
2
3
4
    int i=0;
    while(true) {
      System.out.println(i++);
    }

Output:

1
2
3
4
5
6
0
1
2
3
4
...

Another example of an infinite while loop can happen when you accidentally place a semicolon after the while loop declaration. You might think the loop would execute normally and exit but it will be in an infinite loop with nothing displayed to the output:

1
2
3
4
5
6
7
8
9
10
11
    String [] myStrings  = {
      "alpha",
      "beta",
      "gamma",
      "delta"
    };

    int i=0;
    while(i<myStrings.length); {
      System.out.println(myStrings[i++]);
    }

Further Reading

The while and do-while Statements – The Java™ Tutorials
while Loop in java (tutorials point)
Java Programming Tutorial – 13 – While Loop (YouTube)

Do-While Loop

Do-while loops (aka do loops) are best used when you don’t know how many times you have to loop over something AND you want to execute the loop at least once. For example, if a program continuously takes input from the user and outputs it, until the user enters the letter “q”, then you would use a do-while loop since you would need to take the user’s input at least once.

Do-While Loop Structure

Just like while loops, do-while loops in Java have a simpler structure than for loops because they don’t have an initialization or a step value. They are similar to while loops but the order of operations is different. Their structure follows this order of execution:

1) loop body
2) boolean condition – if true, continue to next step; if false, exit loop
3) repeat from step 1 (loop body)

The difference between a do-while loop and a while loop is that the do-while loop executes the body first before evaluating the boolean condition, whereas the while loop first evaluates the boolean condition before executing the loop body.

java-do-while-loop-diagram

Example – Integer Array

To loop over an integer array with a do-while loop, we initialize a local variable to 0, which is the first array index. The boolean expression tests to make sure that i is less than the size of the array because the last array index will be 1 less than the size of the array. We also increment the local variable inside the loop body. Since the do loop executes the loop body first before checking the boolean expression, the code would throw a ArrayIndexOutOfBoundsException if the array was empty.

1
2
3
4
5
    int [] intArray = {1, 3, 5, 7, 9};
    int i=0;
    do {
      System.out.println(intArray[i++]);
    } while(i<intArray.length);

Output:

1
2
3
4
5
1
3
5
7
9

Example – String Characters

To loop over a string of characters with a do-while loop, we initialize a local variable to 0 and then use the String.charAt() method to get the character at the specified index. As in the previous example, we increment the local variable inside the loop body. If the string was empty, the code would cause a StringIndexOutOfBoundsException.

1
2
3
4
5
6
    String myString = "hello";
     
    int i=0;
    do {
      System.out.print(myString.charAt(i++));
    } while(i<myString.length());

Output:

1
hello

Example – String Array

To loop over a string of characters with a do-while loop, we initialize a local variable to 0 and then use the String.charAt() method to get the character at the specified index. As in the previous example, we increment the local variable inside the loop body. The code would throw a ArrayIndexOutOfBoundsException if the array was empty.

1
2
3
4
5
6
7
8
9
10
11
    String [] myStrings  = {
      "alpha",
      "beta",
      "gamma",
      "delta"
    };

    int i=0;
    do {
      System.out.println(myStrings[i++]);
    } while(i<myStrings.length);

Output:

1
2
3
4
alpha
beta
gamma
delta

Example – List

To loop over a java.util.List with a do-while loop, we initialize a local variable to 0 to use it as the list index and keep looping until 1 less than the size of the list. We use the List.get() method to retrieve the specific list element with the local variable and increment it within the loop body. The code would throw a ArrayIndexOutOfBoundsException if the list was empty.

1
2
3
4
5
6
7
8
9
10
    List<String> myList = new ArrayList<String>();
    myList.add("alpha");
    myList.add("beta");
    myList.add("gamma");
    myList.add("delta");

    int i=0;
    do {
      System.out.println(myList.get(i++));
    } while(i<myList.size());

Output:

1
2
3
4
alpha
beta
gamma
delta

Example – Set 1

We can’t iterate over a java.util.Set directly with a do-while loop by accessing its elements with an index the way we did for a list. Instead, we need to convert the set into an array first and then iterate over the array. The converted array is a generic array of Objects even though the original set consisted of strings. After the conversion to the array, we iterate over it in a similar way as we did for an array of integers. The code would throw a ArrayIndexOutOfBoundsException if the set was empty.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    Set<String> mySet = new HashSet<String>();
    mySet.add("alpha");
    mySet.add("alpha");
    mySet.add("beta");
    mySet.add("gamma");
    mySet.add("gamma");
    mySet.add("delta");

    Object [] mySetStrings = mySet.toArray();

    int i=0;
    do {
      System.out.println(mySetStrings[i++]);
    } while(i<mySetStrings.length);

Output:

1
2
3
4
alpha
delta
beta
gamma

Example – Set 2

We can also use a do-while loop to iterate over a java.util.Set by converting it first to an array of the specific type. In this example, we’re iterating over the set’s elements in a do-while loop after they’ve been converted to an array of strings. The code would throw a ArrayIndexOutOfBoundsException if the set was empty.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Set<String> mySet = new HashSet<String>();
    mySet.add("alpha");
    mySet.add("alpha");
    mySet.add("beta");
    mySet.add("gamma");
    mySet.add("gamma");
    mySet.add("delta");

    String [] mySetStrings = mySet.toArray(new String[mySet.size()]);

    int i=0;

    do {
      System.out.println(mySetStrings[i++]);
    } while(i<mySetStrings.length);

Output:

1
2
3
4
alpha
delta
beta
gamma

Example – Map

To iterate over a java.util.Map with a do-while loop, we first get the map’s set of keys and then convert that java.util.Set to a String array. The code would throw a ArrayIndexOutOfBoundsException if the map was empty.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Map <String,String>myMap = new HashMap<String,String>();
    myMap.put("a", "alpha");
    myMap.put("b", "beta");
    myMap.put("c", "gamma");
    myMap.put("d", "delta");

    Set<String> keySet = myMap.keySet();

    String [] keys = keySet.toArray(new String [keySet.size()]);

    int i=0;
    do {
      System.out.println("Key:" + keys[i] + " Value:" + myMap.get(keys[i]));
      i++;
    } while(i<keys.length);

Output:

1
2
3
4
Key:a Value:alpha
Key:b Value:beta
Key:c Value:gamma
Key:d Value:delta

Example – Infinite Loop

An infinite while loop will occur when the boolean condition is always true. This loop could still be broken out of if inside the loop body the break or return statement was used.

1
2
3
4
    int i=0;
    do {
      System.out.println(i++);
    } while(true);

Output:

1
2
3
4
5
6
0
1
2
3
4
...

Further Reading

The while and do-while Statements – The Java™ Tutorials
Java Programming Tutorial – 24 – do while Loops (YouTube)
Do while syntax for java – debugging exercise

Loop Control Flow

Break Statement

Sometimes it’s necessary to exit a loop before the loop has finished fully iterating over all the step values. For example, looping over a list of numbers until you find a number that satisfies a certain condition. Or looping over a stream of characters from a file until a certain character is read.

In the following example, we’re using a simple for loop to print out values from 0 to 9:

1
2
3
    for(int i=0; i<10; i++) {
      System.out.println(i);
    }

Output:

1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9

Now if we add a break statement when i==4, our code will break out of the loop once i equals 4. You can use the break statement to break out of for loops, while loops and do-while loops. The break statement will only break out of the current loop. In order to break out of an outer loop from a nested inner loop, you would need to use labels with the break statement.

1
2
3
4
5
6
    for(int i=0; i<10; i++) {
      System.out.println(i);
      if(i==4) {
        break;
      }
    }

Output:

1
2
3
4
5
0
1
2
3
4

Continue Statement

Java’s continue statement skips over the current iteration of a loop and goes directly to the next iteration. After calling the continue statement in a for loop, the loop execution will execute the step value and evaluate the boolean condition before proceeding with the next iteration. In the following example, we’re printing out all values from 0 to 9 in a loop but we skip over printing out 4.

1
2
3
4
5
6
    for(int i=0; i<10; i++) {
      if(i==4) {
        continue;
      }
      System.out.println(i);
    }

Output:

1
2
3
4
5
6
7
8
9
0
1
2
3
5 <---- SKIPPED OVER 4 and continued with next loop iteration
6
7
8
9

You can also use the continue statement in a while loop but you would need to iterate the step value within the loop. Note how the i++ iteration is done in two place: right before calling coninue and at the end of the loop body. If i wasn’t incremented before continue, the loop would get stuck in in infinite loop because i would be stuck at 4 and keep calling continue to go to the top of the loop.

1
2
3
4
5
6
7
8
9
    int i=0;
    while(i<10) {
      if(i==4) {
        i++;
        continue;
      }
      System.out.println(i);
      i++;
    }

Output:

1
2
3
4
5
6
7
8
9
0
1
2
3
5 <---- SKIPPED OVER 4 and continued with next loop iteration
6
7
8
9

The continue statement in a do-while loop is used in a similar way as for a while loop – the loop variable has to be incremented manually in two places in the loop body, to prevent an infinite loop condition, just like for a while loop.

1
2
3
4
5
6
7
8
9
    int i=0;
    do {
      if(i==4) {
        i++;
        continue;
      }
      System.out.println(i);
      i++;
    } while(i<10);

Output:

1
2
3
4
5
6
7
8
9
0
1
2
3
5 <---- SKIPPED OVER 4 and continued with next loop iteration
6
7
8
9

Nested Loops

Sometimes it’s necessary to have loops within loops. For example, when reading from a table of data with rows and columns, the first (outer) loop can loop over all the rows and the second (inner) loop can loop over all the columns within each row.

When loops are inside other loops we refer to the inner loops as nested. There could even be multiple layers of nested loops. Here’s an example of a 3 layer nested loop:

1
2
3
4
5
6
7
    for(int i=0; i<5; i++) { //loop 1
      for(int j=0; j<4; j++) {  //loop 2
        for(int k=0; k<2; k++) { //loop 3
          System.out.println("[" + i + "][" + j + "][" + k + "]");
        }
      }
    }

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[0][0][0]
[0][0][1]
[0][1][0]
[0][1][1]
[0][2][0]
[0][2][1]
[0][3][0]
[0][3][1]
[1][0][0]
[1][0][1]
[1][1][0]
[1][1][1]
[1][2][0]
[1][2][1]
[1][3][0]
[1][3][1]
[2][0][0]
[2][0][1]
[2][1][0]
[2][1][1]
[2][2][0]
[2][2][1]
[2][3][0]
[2][3][1]
[3][0][0]
[3][0][1]
[3][1][0]
[3][1][1]
[3][2][0]
[3][2][1]
[3][3][0]
[3][3][1]
[4][0][0]
[4][0][1]
[4][1][0]
[4][1][1]
[4][2][0]
[4][2][1]
[4][3][0]
[4][3][1]

Loop Label

Many earlier programming languages such as C/C++ used the goto keyword to make the program jump or “go to” another part of the program from where it’s currently executing. The goto statement definitely has a bad rap because of its likeliness to make the program harder to understand and to lead to “spaghetti code” where the flow of execution is very hard to follow.

Evils of Goto Statement

Java doesn’t have use the goto keyword even though it is listed as an unused keyword of the language. Java does have labels, which is a limited version of a goto statement within loops to make the program jump to another part of the program.

You can use labels within nested loops by specifying where you want execution to continue after breaking out of an inner loop. Normally, the break statement will only break out of the innermost loop so when you want to break out of an outer loop, you can use labels to accomplish this, essentially doing something similar to a goto statement.

The following example uses 3 loops, all nested within each other. Since there’s no way to completely break out of the outer most loop from inside the inner most loop, we can use the label “outer1” to accomplish this and specify the label next to the break statement.

1
2
3
4
5
6
7
8
9
10
11
    outer1:
    for(int i=0; i<5; i++) {
      for(int j=0; j<4; j++) {
        for(int k=0; k<2; k++) {
          System.out.println("[" + i + "][" + j + "][" + k + "]");
          if(j == 3) {
            break outer1;
          }
        }
      }
    }

Output:

1
2
3
4
5
6
7
[0][0][0]
[0][0][1]
[0][1][0]
[0][1][1]
[0][2][0]
[0][2][1]
[0][3][0]

Notice how the last line displayed is “[0][3][0]” which is where j == 3 and that’s where we called “break outer1;” to break out of the outer most loop. We can also place a label on the second loop to allow breaking out it without breaking out of the entire loop:

1
2
3
4
5
6
7
8
9
10
11
    for(int i=0; i<5; i++) {
      outer2:
      for(int j=0; j<4; j++) {
        for(int k=0; k<2; k++) {
          System.out.println("[" + i + "][" + j + "][" + k + "]");
          if(j == 3) {
            break outer2;
          }
        }
      }
    }

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[0][0][0]
[0][0][1]
[0][1][0]
[0][1][1]
[0][2][0]
[0][2][1]
[0][3][0]  <---- BREAKS OUT OF 2ND LOOP
[1][0][0]
[1][0][1]
[1][1][0]
[1][1][1]
[1][2][0]
[1][2][1]
[1][3][0]  <---- BREAKS OUT OF 2ND LOOP
[2][0][0]
[2][0][1]
[2][1][0]
[2][1][1]
[2][2][0]
[2][2][1]
[2][3][0]  <---- BREAKS OUT OF 2ND LOOP
[3][0][0]
[3][0][1]
[3][1][0]
[3][1][1]
[3][2][0]
[3][2][1]
[3][3][0]  <---- BREAKS OUT OF 2ND LOOP
[4][0][0]
[4][0][1]
[4][1][0]
[4][1][1]
[4][2][0]
[4][2][1]
[4][3][0]  <---- BREAKS OUT OF 2ND LOOP

Notice all the times the code breaks out of the second loop with the “outer2” label. Each time it breaks out, outer most loop gets incremented by 1 and the code continue executing.

You can also use labels with the continue keyword to continue looping from a specific point. Taking the first labelled loop example and just changing one line to specify “continue outer1;” instead of “break outer1;” will cause the loop to continue looping from the “outer1” label instead of breaking out of the loop. Note how each time “continue outer1” is called, the code continues from the outer loop after incrementing the loop index i by 1.

1
2
3
4
5
6
7
8
9
10
    outer1:
    for(int i=0; i<5; i++) {
      for(int j=0; j<4; j++) {
        for(int k=0; k<2; k++) {
          System.out.println("[" + i + "][" + j + "][" + k + "]");
          if(j == 3) {
            continue outer1;
        }
      }
    }

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[0][0][0]
[0][0][1]
[0][1][0]
[0][1][1]
[0][2][0]
[0][2][1]
[0][3][0] <---- CONTINUE WITH LABEL CALLED HERE
[1][0][0] <---- CONTINUES FROM NEXT ITERATION OF OUTER LOOP
[1][0][1]
[1][1][0]
[1][1][1]
[1][2][0]
[1][2][1]
[1][3][0] <---- CONTINUE WITH LABEL CALLED HERE
[2][0][0] <---- CONTINUES FROM NEXT ITERATION OF OUTER LOOP
[2][0][1]
[2][1][0]
[2][1][1]
[2][2][0]
[2][2][1]
[2][3][0] <---- CONTINUE WITH LABEL CALLED HERE
[3][0][0] <---- CONTINUES FROM NEXT ITERATION OF OUTER LOOP
[3][0][1]
[3][1][0]
[3][1][1]
[3][2][0]
[3][2][1]
[3][3][0] <---- CONTINUE WITH LABEL CALLED HERE
[4][0][0] <---- CONTINUES FROM NEXT ITERATION OF OUTER LOOP
[4][0][1]
[4][1][0]
[4][1][1]
[4][2][0]
[4][2][1]
[4][3][0]

Return Statement Within Loops

Java’s return statement is used to exit program execution from a method. It can also be use to exit from a loop (or nested loop) within a method. Its behavior is similar to the break statement but whereas the break statement exits the current loop, the return statement exits the entire method.

1
2
3
4
5
6
    for(int i=0; i<10; i++) {
      if(i==4) {
        return; //exit current method
      }
      System.out.println(i);
    }

Output:

1
2
3
4
0
1
2
3

Local Variable Scope

Local variables defined within loops are visible only within the loop. If you attempt to use one of these variables outside the loop, you will get a compilation error. For example, for loops usually initialize loop variable and these are only accessible from within the for loop. The following example uses a do-while loop with 2 local variables: i and j. i was defined before the loop so it’s still accessible after the loop. But j is defined from within the loop so the compiler will throw an error when trying to access j outside the loop.

1
2
3
4
5
6
7
8
    int i=0;
    do {
      int j = 0; //defined in loop
      System.out.println(i++);
    } while(i < 5);
   
    i = 0; //no error - defined before loop
    j = 1; //compile error - defined within loop

Output:

1
2
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
  j cannot be resolved to a variable

Further Reading

Breaking out of nested loops in Java
“loop:” in Java code. What is this, why does it compile?

Loop Errors and Exceptions

Loops have their own unique errors and exceptions that we will examine below.

Infinite Loops

We already covered infinite loops as they pertain to for loops, while loops and do-while loops. The main idea is that the loop never exits because the boolean condition is always true.

Here’s another example of an infinite for loop where a subtle error is introduced. The code uses 2 loop variables: i and j. Note how the boolean expression uses i but the step value uses j. This will cause an infinite loop because i never gets incremented and the boolean expression will always evaluate to true.

1
2
3
4
5
    int [] intArray = {1, 3, 5, 7, 9};
   
    for(int i=0, j=0; i<intArray.length; j++) {
      System.out.println(intArray[i]);
    }

Output:

1
2
3
4
5
6
7
1
1
1
1
1
1
...

Array Index Out Of Bounds Exception

This exception can occur when the loop tries to access an array element beyond the size of the array. The errors can be quite subtle as shown in the following example:

1
2
3
4
5
    int [] intArray = {1, 3, 5, 7, 9};

    for(int i=0; i<=intArray.length; i++) {
      System.out.println(intArray[i]);
    }

Output:

1
2
3
4
5
6
1
3
5
7
9
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5

The exception occurs because the loop’s boolean expression checks if i is less than or equal to the size of the array. But since the array has 5 elements, the last valid array index will be 4. So when the loop tries to access the array with index 5, the JVM throws a ArrayIndexOutOfBoundsException. This is why the output shows a “5” where the exception is thrown.

The next example uses a do loop to display the elements in an array. Since the do loop executes the loop body first before checking the boolean expression, this code throws an ArrayIndexOutOfBoundsException because an empty array will not have a single element.

1
2
3
4
5
    int [] intArray = {};
    int i=0;
    do {
      System.out.println(intArray[i++]);
    } while(i<intArray.length);

Output:

1
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0

String Index Out of Bounds Exception

This exception can occur when accessing an element within a string that doesn’t exist. It’s similar to ArrayIndexOutOfBoundsException but more specific to strings. In the following do-while loop, the code is trying to access the first character in an empty string.

1
2
3
4
5
6
    String myString = "";
     
    int i=0;
    do {
      System.out.print(myString.charAt(i++));
    } while(i<myString.length());

Output:

1
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0

Out of Memory Error

Often loops encounter a java.lang.OutOfMemoryError when each loop iteration allocates more and more memory. Here is a simple example showing how each loop iteration allocates memory for a progressively larger array of integers until the JVM throws an OutOfMemoryError. Each loop iteration multiples the size of the array by 5.

1
2
3
4
5
6
    int arraySize = 100;
    for(int i=0; i<15; i++) {
      int [] intArray = new int[arraySize];
      System.out.println("Created integer array of size: " + arraySize);
      arraySize *= 5;
    }

Output:

1
2
3
4
5
6
7
8
9
10
11
Created integer array of size: 100
Created integer array of size: 500
Created integer array of size: 2500
Created integer array of size: 12500
Created integer array of size: 62500
Created integer array of size: 312500
Created integer array of size: 1562500
Created integer array of size: 7812500
Created integer array of size: 39062500
Created integer array of size: 195312500
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

Further Reading

Very simple for loop error Java
For Loop in Java | Important points
java.lang.ArrayIndexOutOfBoundsException: 3 in a while loop