Java nested loops
A loop is called nested if it is placed inside another loop. On the first pass, the outer loop calls the inner loop, which runs to completion, after which control is transferred to the body of the outer loop. On the second pass, the outer loop calls the inner one again. And so on until the outer loop ends. There are four types of loops in Java:for loop
while loop
do...while loop
for-each loop
How Java nested loops work
Probably the most used loop in Java is for, in large part because it is quite versatile and the code with it is quite easy to read. Here is the general syntax for nested for loop:
// outer loop
for (initialization; condition; increment) {
//write here your code
//nested loop
for(initialization; condition; increment) {
//write here your code
}
..
}
How does he work? The outer loop starts. Then the nested for loop starts the work and goes through its index until the condition is met, and again passes the work to the outer loop, and this happens until the condition of the outer loop is met. Sounds a little tricky, doesn't it? Well, It will be much easier to understand with a specific example, so let's move on to it.
Nested for loop code example
Here is one classic example. Let’s print out a half pyramid using two for loops. One of them is nested.
public class NestedLoopsDemo1 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
for (int j = 0; j<=i; j++)
System.out.print("*");
System.out.println();
}
}
}
The output is:
Nested while loop code example
public class NestedLoopsDemo2 {
public static void main(String[] args) {
int i = 0;
while (i < 10) {
int j = 0;
while (j <= i) {
System.out.print("*");
j++;
}
System.out.println();
i++;
}
}
}
The output is just the same as in the previous example:
Nested foreach loops code example
for-each loop can be nested like usual for loop. Here is the example for nested for-each loop which iterates 2-dimensional array.
public class NestedLoops2 {
public static void main(String[] args)
{
int[][] mainArray = { {5, 4, 3, 2, 1}, {7, 8, 9, 10, 11} };
for (int[] myArray : mainArray)
{
for (int i : myArray)
{
System.out.print(i+" ");
}
System.out.println("");
}
}
}
The output is:
Mixed for and while loop example
Sometimes we can nest different types of loops inside each other. For example, for inside while or for inside for-each. However, it’s not the best programming practice. Such constructs significantly impair the readability of the code. So professional programmers try not to mix one with the other. Well, they do, but only if it’s really needed. And one more little rule: if you are choosing between while and for, use for where possible. Nevertheless, here we are going to have an example of using a for loop inside the while. Let's build our semi-pyramid again.
public class NestedLoopsDemo2 {
public static void main(String[] args) {
int i = 0;
while (i < 10) {
for (int j = 0; j <= i; j++) {
System.out.print("*");
}
System.out.println();
i++;
}
}
}
The output is without surprises:
Tracing the Execution of Nested Loops
Understanding how nested loops execute is crucial for debugging and writing efficient code. Tracing involves systematically following the iterations of each loop to understand the flow and ensure the expected behavior.
Nested loops consist of an outer loop and one or more inner loops. The inner loop completes all its iterations for each single iteration of the outer loop.
Example: Simple Nested Loop
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
System.out.println("Outer: " + i + ", Inner: " + j);
}
}
Output:
Outer: 1, Inner: 1 Outer: 1, Inner: 2 Outer: 2, Inner: 1 Outer: 2, Inner: 2 Outer: 3, Inner: 1 Outer: 3, Inner: 2
Step-by-Step Execution of Nested Loops
To trace a nested loop, follow the iteration count and print intermediate results. Let’s break down the example:
- Outer Loop (i = 1): Enters the first iteration of the outer loop.
- Inner Loop (j = 1 to 2): Executes the inner loop twice while
i
remains 1. - Outer Loop (i = 2): Proceeds to the second iteration of the outer loop.
- Inner Loop (j = 1 to 2): Executes the inner loop twice while
i
remains 2. - Outer Loop (i = 3): Enters the third and final iteration of the outer loop.
- Inner Loop (j = 1 to 2): Executes the inner loop twice while
i
remains 3.
Using print statements or debugging tools helps track these iterations in real-time during program execution.
Example: Visualizing Output in a Grid
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
System.out.print("(" + i + "," + j + ") ");
}
System.out.println(); // Move to the next line after each row
}
Output:
(1,1) (1,2) (1,3) (2,1) (2,2) (2,3) (3,1) (3,2) (3,3)
Common Pitfalls and Debugging Techniques
Pitfall: Infinite Loops
Nested loops can accidentally run infinitely if the termination condition is not properly defined. For example:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j > 0; j++) { // Infinite loop
System.out.println(i + "," + j);
}
}
Solution: Ensure that each loop has a termination condition that will eventually be met.
Pitfall: Incorrect Loop Boundaries
Using incorrect start or end values can lead to unexpected results, such as skipping iterations or out-of-bounds errors.
// Incorrect: Starts from 0 instead of 1
for (int i = 0; i < 3; i++) {
for (int j = 1; j <= 3; j++) {
System.out.print("(" + i + "," + j + ") ");
}
}
Solution: Double-check loop boundaries and initialization conditions during coding.
Debugging Techniques
- Print Statements: Add print statements to display the values of loop variables during each iteration.
- Debugging Tools: Use IDE debugging tools to set breakpoints and step through the loop execution.
- Manual Tracing: Use pen and paper to simulate the iterations and predict the output before running the code.
Using break in Nested Loops
The break
statement is used to terminate the nearest enclosing loop. When working with nested loops, break
can be particularly useful for exiting an inner loop without affecting the outer loop.
Example: Breaking Out of an Inner Loop
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 3) {
break; // Exit the inner loop when j equals 3
}
System.out.println("Outer: " + i + ", Inner: " + j);
}
}
Output:
Outer: 1, Inner: 1 Outer: 1, Inner: 2 Outer: 2, Inner: 1 Outer: 2, Inner: 2 Outer: 3, Inner: 1 Outer: 3, Inner: 2
In this example, the break
statement ensures that the inner loop stops executing as soon as j == 3
, but the outer loop continues to the next iteration.
Using Labeled break
When dealing with deeply nested loops, you can use a labeled break
to exit multiple levels of loops:
outerLoop:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 3) {
break outerLoop; // Exit the outer loop
}
System.out.println("Outer: " + i + ", Inner: " + j);
}
}
Output:
Outer: 1, Inner: 1 Outer: 1, Inner: 2
The labeled break
immediately terminates both the inner and outer loops when j == 3
.
Using continue in Nested Loops
The continue
statement skips the current iteration of the nearest enclosing loop and proceeds with the next iteration. In nested loops, it is often used to bypass specific iterations in the inner loop without interrupting the overall flow.
Example: Skipping Iterations in an Inner Loop
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 3) {
continue; // Skip the rest of this iteration when j equals 3
}
System.out.println("Outer: " + i + ", Inner: " + j);
}
}
Output:
Outer: 1, Inner: 1 Outer: 1, Inner: 2 Outer: 1, Inner: 4 Outer: 1, Inner: 5 Outer: 2, Inner: 1 Outer: 2, Inner: 2 Outer: 2, Inner: 4 Outer: 2, Inner: 5 Outer: 3, Inner: 1 Outer: 3, Inner: 2 Outer: 3, Inner: 4 Outer: 3, Inner: 5
In this example, the continue
statement skips the iteration where j == 3
, while the outer loop and remaining inner loop iterations proceed as normal.
Using Labeled continue
Just like with break
, you can use a labeled continue
to skip iterations of an outer loop:
outerLoop:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 5; j++) {
if (j == 3) {
continue outerLoop; // Skip the rest of the current outer loop iteration
}
System.out.println("Outer: " + i + ", Inner: " + j);
}
}
Output:
Outer: 1, Inner: 1 Outer: 1, Inner: 2 Outer: 2, Inner: 1 Outer: 2, Inner: 2 Outer: 3, Inner: 1 Outer: 3, Inner: 2
The labeled continue
skips all remaining iterations of the inner loop and jumps directly to the next iteration of the outer loop when j == 3
.
Practical Applications of break and continue
- Filtering Data: Skip unwanted entries in a dataset using
continue
. - Early Exit: Use
break
to terminate loops when a specific condition is met, such as finding a required value. - Optimizing Performance: Avoid unnecessary iterations to save computation time in large datasets.
GO TO FULL VERSION