Overview of This Lesson

In an earlier lesson we talked about nested selection statements and how we use them for more complex decision-making in our programs. We can also nest loops inside each other when we want to repeat statements at multiple levels. For example, you might want to print some data in rows (a single loop) or you might want to perform several calculations in each row (a loop for the calculations inside a loop that prints rows). Nested loops are a very popular construct in programming, so it's important to spend some time on some examples and exercises that use nested loops.

Later in this lesson, we'll also look at some examples of a variety of nested structures: you can nest selections inside loops, or nest loops inside selections!

Pre-Requisites

Before doing this lesson, make sure you've completed the lessons nested selections, while loops, and counted for loops.

Nested Loops

Nested loops are simply a loop inside another loop. We usually refer to the loop on the outside as "the outer loop" and the loop that is nested on the inside as "the inner loop". The best way to understand nested loops is with some examples.

The example below shows how nested loops execute. Note that the inner loop completes all its iterations for each iteration of the outer loop.

for (int i = 1; i <= 5; i++) {   // start of outer loop 
    System.out.println("\ni is now " + i);   
    for(int j = 1; j <= 4; j++) {   // start of inner loop 
        System.out.print("  j = " + j);      
    }  // end of inner loop 
}  // end of outer loop 

This code segment would produce the following output:

i is now 1
j = 1  j = 2  j = 3  j = 4
i is now 2
j = 1  j = 2  j = 3  j = 4
i is now 3
j = 1  j = 2  j = 3  j = 4
i is now 4
j = 1  j = 2  j = 3  j = 4
i is now 5
j = 1  j = 2  j = 3  j = 4

Nested loops are often used to handle or display tabular information. The trick to making this work is to remember that usually the outer loop prints a row, and the inner loop prints each column in a row.

public class Main {
    
  public static final double KM_PER_MI = 1.61;
    
  public static void main(String[] args) {
      
        System.out.println("Miles to Kilometers:");
        
        // column headings
        System.out.print(" ".repeat(3)); // 3 spaces
        for (int i = 1; i <= 10; i++) {
            System.out.printf("%7d", i);
        }
        System.out.println(); // newline after column headings
        
        for (int row = 1; row <= 10; row++) {
            
            // row heading for this row:
            System.out.printf("%4d", row);
            
            // a row of values
            for (int mi = 1; mi <= 10; mi++) {
                double km = row * mi * KM_PER_MI;
                System.out.printf("%7.1f", km);
            }
            
            // newline at the end of a row
            System.out.println();
        }
  }
}

Exercises

1. What's the output of each of the following programs?

Example a:

public class ExerciseA {

    public static void main(String[] args) {

        for (int i=0; i<=5; i++) {
            System.out.print(i + ":  ");
            for (int j=1; j<3; j++) {
                System.out.print((i * j) + " ");
            }
            System.out.println();
        }
    }
}

Example b:

public class ExerciseB {

    public static void main(String[] args) {

        for (int i=0; i<=5; i++) {
            System.out.print(i + ":  ");
            for (int j=3; j>0; j--) {
                System.out.print((i * j) + " ");
            }
            System.out.println();
        }
    }
}

2. Use nested loops to print the following table:

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

3. Use nested loops to print a square of asterisks (*) with a given number of rows and columns. E.g. if the user enters 3, it would print:

***
***
***

If the user enters 5, it would print:

*****
*****
*****
*****
*****

4. You and three of your classmates go bowling and want to track and display your results for three games. Write a program that prompts the user to enter the score for each player for each of the three games, and then displays the average score for each player. Sample output is shown below (prompts in navy blue, inputs in red, output in black):

Scores for Player 1
Game 1: 200
Game 2: 205
Game 3: 210
Average Score: 205.00

Scores for Player 2
Game 1: 198
Game 2: 182
Game 3: 201
Average Score: 193.67

Scores for Player 3
Game 1: 252
Game 2: 267
Game 3: 281
Average Score: 266.67

Scores for Player 4
Game 1: 207
Game 2: 243
Game 3: 199
Average Score: 216.33

1. What's the output of each of the following code segments?

Example a.

0:  0 0 
1:  1 2 
2:  2 4 
3:  3 6 
4:  4 8 
5:  5 10

Example b.

0:  0 0 0 
1:  3 2 1 
2:  6 4 2 
3:  9 6 3 
4:  12 8 4 
5:  15 10 5

Question 2:

solution to question 2
Question 2. table of values

Question 3:

solution to question 3
Question 3. box of *'s

Question 4:

solution to question 4
Question 4. average scores

Nesting Other Structures

You can also nest selections inside loops, and loops inside selections. For example, determine the output of each of the following code segments:

// first code segment
for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0)
        System.out.println(i);
}

In this first example, the loop iterates 10 times (from 1 to 10, inclusive). For each iteration, the counter value i is checked to see if it is even. If i is even, then the value of i is printed. If i is odd, nothing is printed. Therefore, the output is

2
4
6
8
10
// second code segment:
// first, assume user enters 5 for high number and 1 for low number
// second, assume user enters 4 for high number and 10 for low number

System.out.println("Enter the high number:");
int high = Integer.parseInt(keysIn.readLine());
System.out.println("Enter the low number:");
int low = Integer.parseInt(keysIn.readLine());

if (high > low)  {
    for (int i = low; i <= high; i++)
        System.out.println(i);
} else
    System.out.println("Your low value must be smaller " +
            "than your high value!");

If the user enters 5 for the high number and 1 for the low number, the program prints the values from 1 to 5 (one per line). The if statement checks first to make sure the high numbers is greater than the low number. If this is true, the for loop is executed.

If the user enters 4 for the high number and 10 for the low number, the if statement's condition is false (4 is not greater than 10). This causes the else block to execute, which prints the error message on the screen.

Exercises

1. In the counted for loops lesson you wrote a for-loop that printed a Fahrenheit to Celsius temperature table. Modify this program:

In this new version, the user enters the starting value and the ending value for the Fahrenheit values to convert into Celsius values. If the user enters a start value that is greater than the ending value, display the table from highest to lowest, instead of lowest to highest.

2. A user wants to find out the alpha grade for each of their final grades this term. Write a program that allows the user to enter any number of final grades that they want, and display the alpha grade according to the following grading system:

Grading System
Grade Range Grade Points
>= 90 A+
>= 80, < 90 A
>= 75, < 80 B+
>= 70, < 75 B
>= 65, < 70 C+
>= 60, < 65 C
>= 50, < 60 D
< 50 F

Question 1:

solution to question 1
Question 1. fahrenheit/celsius conversion

Question 2:

solution to question 2
Question 2. grades to alpha grades

Exercises

1. Use nested loops to print a triangle with a given number of rows. E.g. if the user enters 3, it would print:

*
**
***

If the user enters 5, it would print:

*
**
***
****
*****

2. Write a program that plays a simple dice game: repeatedly roll dice (generate 2 random numbers between 1 and 6) as long as the user wishes to play. For each roll, display "You Win!" if "doubles" are rolled (both dice show the same value), and display "You lose!" if the two dice rolls are different.

Regardless of the result, display the rolls of the dice.

After each roll, ask the user if they'd like to continue playing (Y/N). If they wish to continue, roll again. If they want to quit, stop rolling.

After the user quits, display the total number of rolls, the total number of winning rolls, and the percentage of wins e.g. 20 rolls with 5 wins would be 25%.

3. Write a program that calculates the average final grade for a student who's taken some unknown number of courses. The final grade entered must be greater than or equal 0: if the user enters a negative grade, display an error message and ask again.

Question 1:

question 1 solution
Question 1. print triangle

Question 2:

public class Game {

    public static void main(String[] args) {
                    
        Scanner in = new Scanner(System.in);
        char go = 'y';
        int numRolls = 0, numWins = 0;
        
        do {
            int die1 = (int)(Math.random() * 6 + 1);
            int die2 = (int)(Math.random() * 6 + 1);
            
            System.out.printf("[%d, %d] ", die1, die2);
            if (die1 == die2) {
                System.out.println("You win!");
                numWins++;
                
            } else {
                System.out.println("You lose :(");
            }
            
            numRolls++;
            
            System.out.print("Play again? (Y/N) ");
            go = in.next().toLowerCase().charAt(0);
        } while (go == 'y');
        
        double percentageWins = (double)numWins / numRolls * 100;
        System.out.printf("Number of Rolls: %d\nNumber of Wins: %d (%.1f%%)\n",
            numRolls, numWins, percentageWins);
  }
}
Question 2. dice rolling game

Question 3:

question 1 solution
Question 3. calculate final grade