Java Nested Loops
Updated 8 min read Aimerscrew
Some data has two dimensions: rows and seats in a cinema, days and hours in a calendar, rows and columns in a multiplication table. To visit every cell, you need a loop inside a loop. These are called Java nested loops. In this lesson, you'll learn exactly how nested loops run, print classic star and number patterns, build tables and grids, and get a feel for why nested loops can slow programs down.
🌍 Real-life example
A clock is a nested loop. The minute hand (inner loop) goes all the way around from 0 to 59, and only then does the hour hand (outer loop) move forward by one. Then the minute hand does its full lap again. The inner loop always finishes completely before the outer loop takes its next step.
What are nested loops in Java?
A nested loop is a loop written inside the body of another loop. The first is the outer loop; the one inside is the inner loop. You can nest any loop type in any other: a for loop inside a for loop is the most common, but a for inside a while loop works too.
public class SeatLabels {
public static void main(String[] args) {
for (char row = 'A'; row <= 'C'; row++) {
for (int seat = 1; seat <= 5; seat++) {
System.out.print(row + "" + seat);
if (seat < 5) {
System.out.print(" "); // space between seats, not after the last
}
}
System.out.println();
}
}
}
A1 A2 A3 A4 A5
B1 B2 B3 B4 B5
C1 C2 C3 C4 C5
A few details make this work. First, System.out.print (without ln) keeps printing on the same line, and the empty System.out.println() after the inner loop ends each row. Second, the small if puts a space between seats but not after the last one. Third, row + "" + seat joins the letter and number as text. Writing just row + seat would add the character's numeric code to the number instead, because a char is a number underneath.
How do nested loops execute?
For each iteration of the outer loop, the inner loop starts from scratch and runs all its iterations. Only then does the outer loop move on. With 3 rows and 5 seats, the inner body runs 3 × 5 = 15 times.
You can watch the order by printing both counters:
public class LoopOrder {
public static void main(String[] args) {
for (int outer = 1; outer <= 2; outer++) {
for (int inner = 1; inner <= 3; inner++) {
System.out.println("outer = " + outer + ", inner = " + inner);
}
}
}
}
outer = 1, inner = 1
outer = 1, inner = 2
outer = 1, inner = 3
outer = 2, inner = 1
outer = 2, inner = 2
outer = 2, inner = 3
Printing a full multiplication table
In the for loop lesson, you printed one row of a times table. Wrap that loop in another loop and you get the whole table. %4d pads every number to 4 characters so the columns line up (see Java output formatting):
public class MultiplicationTable {
public static void main(String[] args) {
int size = 6;
for (int row = 1; row <= size; row++) {
for (int col = 1; col <= size; col++) {
System.out.printf("%4d", row * col);
}
System.out.println();
}
}
}
1 2 3 4 5 6
2 4 6 8 10 12
3 6 9 12 15 18
4 8 12 16 20 24
5 10 15 20 25 30
6 12 18 24 30 36
How do you print star patterns with nested loops?
Pattern programs are a classic way to practice nested loops, and they show up in coding interviews. The trick: the outer loop controls the rows, and the inner loop controls what goes in each row. Often the inner loop's limit depends on the outer counter.
Right triangle
public class StarTriangle {
public static void main(String[] args) {
int height = 5;
for (int row = 1; row <= height; row++) {
for (int star = 1; star <= row; star++) {
System.out.print("*");
}
System.out.println();
}
}
}
*
**
***
****
*****
Row 1 prints 1 star, row 2 prints 2 stars, and so on, because the inner condition is star <= row.
Centered pyramid
A pyramid needs two inner loops per row: one for the leading spaces and one for the stars. Row r has height - r spaces and 2 * r - 1 stars:
public class StarPyramid {
public static void main(String[] args) {
int height = 4;
for (int row = 1; row <= height; row++) {
for (int space = 1; space <= height - row; space++) {
System.out.print(" ");
}
for (int star = 1; star <= 2 * row - 1; star++) {
System.out.print("*");
}
System.out.println();
}
}
}
*
***
*****
*******
Number triangle
public class NumberTriangle {
public static void main(String[] args) {
for (int row = 1; row <= 4; row++) {
for (int n = 1; n <= row; n++) {
System.out.print(n);
if (n < row) {
System.out.print(" ");
}
}
System.out.println();
}
}
}
1
1 2
1 2 3
1 2 3 4
💡 Tip
Before coding any pattern, write a small table on paper: row number, how many spaces, how many symbols. Once you spot the formula (like 2 * row - 1), the loops almost write themselves.
Example: a parking garage map
Nested loops are the natural way to walk through a grid. Here, a garage has 3 levels with 5 spots each. The occupied spots are stored in one String, level after level (X = taken, . = free), so the spot on level lvl at position spot sits at index lvl * 5 + spot. You'll store grids more naturally in Java multidimensional arrays.
public class GarageMap {
public static void main(String[] args) {
String spots = "XX.X." + ".XXX." + "X....";
int levels = 3;
int perLevel = 5;
int free = 0;
for (int lvl = 0; lvl < levels; lvl++) {
System.out.print("Level " + (lvl + 1) + ":");
for (int spot = 0; spot < perLevel; spot++) {
char status = spots.charAt(lvl * perLevel + spot);
System.out.print(" " + status);
if (status == '.') {
free++;
}
}
System.out.println();
}
System.out.println("Free spots: " + free);
}
}
Level 1: X X . X .
Level 2: . X X X .
Level 3: X . . . .
Free spots: 8
When the inner loop starts from the outer counter
In a league where every team plays every other team once, team 1 plays teams 2, 3 and 4, team 2 plays 3 and 4 (it already played team 1), and so on. Starting the inner loop at home + 1 avoids duplicates and teams playing themselves:
public class LeagueFixtures {
public static void main(String[] args) {
int teams = 4;
int matches = 0;
for (int home = 1; home <= teams; home++) {
for (int away = home + 1; away <= teams; away++) {
System.out.println("Team " + home + " vs Team " + away);
matches++;
}
}
System.out.println("Total matches: " + matches);
}
}
Team 1 vs Team 2
Team 1 vs Team 3
Team 1 vs Team 4
Team 2 vs Team 3
Team 2 vs Team 4
Team 3 vs Team 4
Total matches: 6
Why can nested loops be slow?
Every extra level of nesting multiplies the work. If both loops run n times, the inner body runs n × n times. Programmers describe this growth with time complexity; a double loop like this is called O(n²), read "order n squared". Let's count:
public class CountSteps {
public static void main(String[] args) {
for (int n = 10; n <= 1000; n *= 10) {
long steps = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
steps++;
}
}
System.out.println("n = " + n + " -> " + steps + " steps");
}
}
}
n = 10 -> 100 steps
n = 100 -> 10000 steps
n = 1000 -> 1000000 steps
| n (items) | One loop: n steps | Two nested loops: n² steps |
|---|---|---|
| 10 | 10 | 100 |
| 1,000 | 1,000 | 1,000,000 |
| 100,000 | 100,000 | 10,000,000,000 |
Making the input 10 times bigger makes a double loop 100 times slower. For small grids that's nothing, but comparing every customer with every other customer in a database of 100,000 is a different story. When a program gets slow, nested loops are the first place to look.
Recap: leaving nested loops with a labeled break
As you learned in Java break and continue, a plain break only exits the inner loop. To stop both loops once you've found an answer, label the outer loop. Here, nuggets come in boxes of 9 and 6, and we want the first way to buy exactly 51:
public class NuggetBoxes {
public static void main(String[] args) {
int target = 51;
search:
for (int nines = 0; nines * 9 <= target; nines++) {
for (int sixes = 0; nines * 9 + sixes * 6 <= target; sixes++) {
if (nines * 9 + sixes * 6 == target) {
System.out.println(nines + " box(es) of 9 + " + sixes + " box(es) of 6 = " + target);
break search;
}
}
}
}
}
1 box(es) of 9 + 7 box(es) of 6 = 51
Without the label, the program would keep searching and also print the other combinations, such as 3 boxes of 9 and 4 boxes of 6.
Common mistakes with nested loops
1. Using the same counter name twice
Declaring int i in both loops doesn't compile ("variable i is already defined"). Use different, meaningful names like row and col.
2. Forgetting println after the inner loop
Without it, every "row" ends up on one long line.
3. Putting the newline inside the inner loop
Then every single item gets its own line and the grid disappears. The println() belongs between the closing brace of the inner loop and the closing brace of the outer loop.
4. Mixing up the counters
Using row in the inner condition when you meant col (or vice versa) produces strange shapes. Clear names make these bugs easy to spot.
Practice exercise
🏋️ Try it yourself
Print an upside-down number triangle of height 5, where each row counts down from the row's size to 1, like a countdown that gets shorter each time. The first row is 5 4 3 2 1 and the last row is 1.
Show solution
public class CountdownTriangle {
public static void main(String[] args) {
for (int size = 5; size >= 1; size--) {
for (int n = size; n >= 1; n--) {
System.out.print(n);
if (n > 1) {
System.out.print(" ");
}
}
System.out.println();
}
}
}
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
What's next?
You've finished the Control Flow chapter. In several examples here, we squeezed a list of seats or parking spots into a String. Java has a much better tool for storing many values: next, learn Java arrays.
Key takeaways
- A nested loop is a loop inside another loop; the inner loop runs completely for every iteration of the outer loop.
- If the outer loop runs a times and the inner loop b times, the inner body runs a × b times.
- For grids and tables, the outer loop usually handles rows and the inner loop handles columns.
- In pattern programs, the inner loop limit often depends on the outer counter, such as star <= row.
- Use print inside the inner loop and println after it to end each row.
- Two nested loops over n items do about n² steps, so they slow down quickly as n grows.
- Use a labeled break to leave both loops at once when a search is finished.
Frequently asked questions
What is a nested loop in Java?
A loop placed inside the body of another loop. For every iteration of the outer loop, the inner loop runs through all of its iterations.
How many times does a nested loop run?
Multiply the iterations: an outer loop of 4 and an inner loop of 6 run the inner body 24 times. If the inner limit depends on the outer counter, add up each row instead.
Can you nest different types of loops in Java?
Yes. You can put a for loop inside a while loop, a while inside a do while, and so on. The rules of each loop stay the same.
How do I break out of two nested loops in Java?
Put a label before the outer loop, such as outer:, and write break outer; inside the inner loop. A plain break only exits the inner loop.
What is the time complexity of nested loops?
Two nested loops that each run n times have O(n squared) time complexity, meaning the work grows with the square of the input size.