Java Pattern Programs

In the last lesson you learned about Java nested loops. Now let’s use them on something fun.

Pattern programs draw squares, triangles, and pyramids out of stars and numbers. By the end, nested loops will finally click.

πŸ€” Why practice with patterns?

To print any shape, you think in rows and columns. The screen is a grid. You fill one row at a time, and inside each row, one column at a time.

  • They force you to use a nested loop, the part of loops people find hardest.
  • You run the code and see the shape, so wrong output is obvious right away.
  • The same row-and-column thinking returns in grids, tables, game boards, and 2D arrays.

Think of a printer. The outer loop is the paper rolling up one line. The inner loop is the ink moving left to right across that line.

🧠 The general method

Don’t picture the whole shape at once. Break every pattern into two questions:

  • How many rows? That becomes the outer loop. It runs once per row.
  • For each row, how many symbols, and which? That becomes the inner loop. It runs once per column.

The key trick: the inner loop can read the outer loop’s counter. So a row’s symbol count can depend on which row you are on. Row 1 prints one star, row 5 prints five. That single idea turns a square into a triangle or pyramid.

You also need print vs println:

  • System.out.print("*") writes the star and stays on the same line.
  • System.out.println("*") writes the star and jumps to a new line.

So inside the inner loop, always use print. After the inner loop finishes a row, call an empty System.out.println() to drop to the next row.

🟦 A solid square

The easiest shape: a 4-by-4 grid of stars. Every row is the same, so the inner loop never changes. The outer loop counts rows, the inner loop prints four stars.

public class Square {
public static void main(String[] args) {
for (int row = 1; row <= 4; row++) { // outer: one pass per row
for (int col = 1; col <= 4; col++) { // inner: print 4 stars
System.out.print("* "); // βœ… print stays on the same line
}
System.out.println(); // move down to the next row
}
}
}

Here’s how it runs:

  • The outer loop runs 4 times, one pass per row.
  • Each pass, the inner loop prints 4 stars left to right with print, so they stay on one line.
  • System.out.println() ends the line and moves down, then the next row repeats.
  • The inner bound is a fixed 4, so every row is the same width. That makes a square.

Output

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

πŸ”Ί A right-angled triangle

Now print one more star each row: row 1 has one, row 2 has two, and so on. That gives a right-angled triangle leaning on the left edge.

The only change from the square is the inner loop’s condition.

public class Triangle {
public static void main(String[] args) {
for (int row = 1; row <= 5; row++) { // 5 rows
for (int col = 1; col <= row; col++) { // βœ… stars equal the row number
System.out.print("* ");
}
System.out.println();
}
}
}

The magic is col <= row. The inner bound is the current row, not a fixed number, so the star count grows with the row:

  • Row 1: col <= 1, prints 1 star.
  • Row 2: col <= 2, prints 2 stars.
  • Row 5: col <= 5, prints 5 stars.

That link between the inner loop and the outer variable is the heart of pattern printing. Change the condition, change the shape.

Output

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

πŸ”» An inverted triangle

Now flip it: wide at the top, narrow at the bottom. Row 1 has five stars, the last row has one.

The new idea here is that the inner count can shrink as the row grows. Count the stars as rows - row + 1.

public class InvertedTriangle {
public static void main(String[] args) {
int rows = 5;
for (int row = 1; row <= rows; row++) {
for (int col = 1; col <= rows - row + 1; col++) { // βœ… shrinks each row
System.out.print("* ");
}
System.out.println();
}
}
}

Check the bound rows - row + 1 on a few rows:

  • Row 1: 5 - 1 + 1 = 5 stars.
  • Row 2: 5 - 2 + 1 = 4 stars.
  • Row 5: 5 - 5 + 1 = 1 star.

To make a row grow, tie the inner bound to row. To make it shrink, tie it to rows - row. Same idea, opposite direction.

Output

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

πŸ”’ A number triangle

Patterns aren’t only stars. Let’s print a triangle where each row counts up to the row number: row 1 is 1, row 2 is 1 2, and so on.

It’s the right-angled triangle again, with the same structure. Only what we print changes.

public class NumberTriangle {
public static void main(String[] args) {
for (int row = 1; row <= 5; row++) {
for (int col = 1; col <= row; col++) {
System.out.print(col + " "); // βœ… print the column counter, not a star
}
System.out.println();
}
}
}

The inner loop already counts col from 1 to the row number. So instead of printing a star, just print col itself. On row 3 it walks 1, 2, 3 and prints 1 2 3.

The loop body is just a slot you fill. A star gives a star triangle, col gives a number triangle, a letter gives letters.

The loop structure stays the same; only what you print changes.

Output

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5

⛰️ A pyramid

A pyramid is a centered triangle. To center the stars, we add leading spaces before them. The top row needs the most spaces; the bottom row needs none.

So each row has two parts, which means two inner loops back to back: spaces first, then stars.

public class Pyramid {
public static void main(String[] args) {
int rows = 5;
for (int row = 1; row <= rows; row++) {
for (int space = 1; space <= rows - row; space++) { // leading spaces
System.out.print(" ");
}
for (int star = 1; star <= 2 * row - 1; star++) { // stars, odd counts
System.out.print("*");
}
System.out.println(); // end this row
}
}
}

Two formulas do the work:

  • Spaces loop runs rows - row times. Row 1 gets 4 spaces, row 5 gets 0. Shrinking spaces tilt the shape toward the center.
  • Stars loop runs 2 * row - 1 times. That gives odd counts 1, 3, 5, 7, 9. An odd number always has one star in the middle, so the shape stays balanced.

Shrinking spaces plus growing odd stars give a centered pyramid. We use print("*") with no trailing space, so the stars pack tightly.

Output

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

If a pyramid looks lopsided, check these two formulas first. Almost every broken pyramid is a count off by one.

⚠️ Common Mistakes

These slip-ups catch almost everyone learning patterns.

Using println instead of print inside the inner loop. Every symbol jumps to a new line, so your wide row becomes a tall column.

// ❌ Wrong: each star lands on its own line
for (int col = 1; col <= 4; col++) {
System.out.println("* ");
}
// βœ… Right: stars stay together on one line
for (int col = 1; col <= 4; col++) {
System.out.print("* ");
}

Forgetting the empty println() after the inner loop. Without it, no row ever ends, so every star prints on one long line. That empty println() is what creates separate rows.

// ❌ Wrong: no newline per row, so everything is one long line
for (int row = 1; row <= 4; row++) {
for (int col = 1; col <= 4; col++) {
System.out.print("* ");
}
}
// βœ… Right: end each row before starting the next
for (int row = 1; row <= 4; row++) {
for (int col = 1; col <= 4; col++) {
System.out.print("* ");
}
System.out.println(); // this line builds the rows
}

Using the wrong inner bound. The inner condition decides the shape. A fixed bound gives a square; a bound tied to row gives a triangle. Mix them up and you get the wrong picture.

// ❌ Wrong: fixed bound, so this prints a square, not a triangle
for (int col = 1; col <= 4; col++) {
System.out.print("* ");
}
// βœ… Right: bound tied to the row, so each row grows
for (int col = 1; col <= row; col++) {
System.out.print("* ");
}

βœ… Best Practices

  • Plan rows and columns before you type. Rows are the outer loop; symbols per row are the inner loop. Planning is the hard part; the code is short.
  • Tie the inner bound to the row for shapes that change. col <= row grows a shape, col <= rows - row shrinks it.
  • Build up one idea at a time. Square, then triangle, then pyramid. Each step adds one new idea, so you know where to look when it breaks.
  • Test with 4 or 5 rows. Small output is easy to eyeball, so you catch an off-by-one right away.
  • Read your output line by line. Count the symbols on each row against your formula. The mismatch points straight at the bug.

🧩 What You’ve Learned

Nicely done. You can draw with loops now.

  • βœ… A nested loop is a loop inside another loop. The outer loop handles rows, the inner loop handles columns.
  • βœ… The method for any pattern: count the rows first, then work out how many symbols each row needs.
  • βœ… Use print for items on the same row, and an empty System.out.println() after the inner loop to start a new row.
  • βœ… Tying the inner bound to the row makes shapes grow (col <= row) or shrink (col <= rows - row).
  • βœ… Pyramids add a spaces loop before the stars to center the shape, using 2 * row - 1 for the odd star counts.
  • βœ… You can fill patterns with stars, numbers, or letters; the loop structure stays the same.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    In a pattern program, what does the outer loop usually control?

    Why: The outer loop runs once per row, and the inner loop fills in each row's columns.

  2. 2

    Why do we use print instead of println inside the inner loop?

    Why: print keeps items on the same row; println would push each one to a new line.

  3. 3

    What does System.out.println() after the inner loop do?

    Why: The empty println() ends the current line, starting a fresh row for the next outer pass.

  4. 4

    How do you make a triangle that grows one star per row?

    Why: Making the inner loop run up to the current row number prints more stars on each lower row.

πŸš€ What’s Next?

You have finished loops. Next is a new building block: arrays. An array stores many values, like a whole list of marks, in a single variable.

Java Introduction to Arrays

Share & Connect