Java ProgramsPatternsPrint Hollow Triangle

Print Hollow Triangle in Java

intermediate·  Patterns  ·  Star Patterns

Problem

A hollow triangle keeps only the two slanted edges and the base filled in — every position strictly inside those edges is left blank.

Given a number of rows, print a left-aligned triangle outline of stars with a blank interior and a solid base.

Input
n = 6
Output
* ** * * * * * * ******

Java Program

Java
public class HollowTriangle { public static void main(String[] args) { int n = 6; for (int i = 1; i <= n; i++) { StringBuilder line = new StringBuilder(); for (int j = 1; j <= i; j++) { if (j == 1 || j == i || i == n) { // edge position, or the solid base row line.append("*"); } else { line.append(" "); } } System.out.println(line); } } }

Output

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

Core Logic

Printing a star only at the first position, the last position of each row, or anywhere in the final row leaves every interior position blank while still closing the shape at the bottom.

How It Works
  1. 1The outer loop runs i from 1 to n, and for each row the inner loop runs j from 1 to i, matching the same widening shape as a solid triangle.
  2. 2A star is printed when j == 1 (the left edge), j == i (the right edge), or i == n (the base row).
  3. 3Every other position — strictly inside a row that isn't the base — prints a blank space instead.
  4. 4Without the last-row exception, the triangle's two slanted edges would never actually meet at a closed bottom.
For n = 6, rows 1 through 5 show only their two edge stars, while row 6 — the base — prints all six stars solid.
💡

Key Point: The base row needs its own special case because j == 1 and j == i alone would leave every row's middle hollow — including the bottom, which would make the shape look open instead of enclosed.

Complexity
Time Complexity: O(n²)Space Complexity: O(1)

Why: The nested loop still visits every position within the triangular grid to decide star-vs-space, a total proportional to n², with only the loop counters kept.

Key Concepts

nested for loopborder conditionsolid base

Approach 2: Java 8

Java
import java.util.stream.Collectors; import java.util.stream.IntStream; public class HollowTriangleStream { public static void main(String[] args) { int n = 6; IntStream.rangeClosed(1, n) .mapToObj(i -> IntStream.rangeClosed(1, i) .mapToObj(j -> (j == 1 || j == i || i == n) ? "*" : " ") .collect(Collectors.joining(""))) .forEach(System.out::println); } }

Output

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

Core Logic

Since each position's edge-or-base status depends only on its own row and column, mapping every column index directly to that test reproduces the outline without visiting neighboring cells.

How It Works
  1. 1IntStream.rangeClosed(1, n) generates one stream element per row i.
  2. 2For each row, an inner IntStream.rangeClosed(1, i) generates that row's column positions j, matching the triangle's widening shape.
  3. 3.mapToObj(j -> (j == 1 || j == i || i == n) ? "*" : " ") tests the same edge-or-base condition the loop version does, per position.
  4. 4Collectors.joining("") concatenates that row's characters with no separator, matching the loop version's plain character append.
For row 4, only j = 1 and j = 4 satisfy the edge test, so the inner stream produces a star, two blanks, and a closing star: * *.
💡

Key Point: The base-row exception is still just one more clause in the same per-cell formula — it maps onto a stream exactly as cleanly as it fits inside a nested loop, with no dependency on any other cell's result.

Complexity
Time Complexity: O(n²)Space Complexity: O(1)

Why: The nested streams still evaluate the edge-or-base condition once per position within the triangular grid, the same total work as the loop version.

Key Concepts

StreamIntStream.rangeClosed()Collectors.joining()

Related Programs