Print Christmas Tree

Java program to print Christmas Tree

The below program uses astricks( * ) to print a christmas tree with any specified size. The program has been written in Java 8 using IntStream.range instead of conventional for-loops.

ChristmasTree tree = new ChristmasTree(7);
tree.print();

The class takes height as an argument and calls print method to draw the tree. The algorithm works by determining the left spaces and stars to be printed on each line.

class ChristmasTree{

    private int height;

    ChristmasTree(int height){
        this.height = height;
    }

    public void print(){

        IntStream.range(0, this.height).forEach((row)->{

            //print spaces
            int spaces = this.height - (row + 1);
            IntStream.range(0, spaces).forEach((i)->{
                System.out.print(" ");
            });

            //print stars
            int stars = row*2+1;
            IntStream.range(0, stars).forEach((i)->{
                System.out.print("*");
            });

            System.out.println();   
        });
    }

}

Logic

2*row+1 is used to decide the number of stars in each row.

For row 0, it will be 2 x 0 + 1 = 1

For row 1, it will be 2 x 1 + 1 = 3

and so on, as they go increasing.

The spaces have to reduce as we go down the tree, So we take height - row to decide the number of spaces. Since, row indexes start with 0, we took height - (row+1)

Refactor

In this version, we added

  1. a StringBuilder to append the spaces and stars and print at once. This will help reduce IO.
  2. this::buildRow calls the buildRow method passing row parameter implicitly.
  3. private methods to print row and spaces. The methods are self explainatory and need no documentation.
import java.util.stream.IntStream;

class ChristmasTree{

    private int height;
    private StringBuilder builder;

    ChristmasTree(int height){
        this.height = height;
        builder = new StringBuilder();
    }

    public void print(){
        IntStream.range(0, height).forEach(this::buildRow);
        System.out.print(builder.toString());
        builder = new StringBuilder(); //to flush old string
    }

    private void buildRow(int row){
        printSpaces(row, builder);
        printStars(row, builder);
        builder.append(System.lineSeparator());
    }

    private void printSpaces(int row, StringBuilder builder){
        int spaces = height - (row + 1);
        IntStream.range(0, spaces).forEach((i)->{
            builder.append(" ");
        });
    }

    private String printStars(int row, StringBuilder builder){
        int stars = row*2+1;
        IntStream.range(0, stars).forEach((i)->{
            builder.append("*");
        });
    }
}

builder = new StringBuilder(); builder is reassigned to another object, so that we can call print() method again and make a big tree.

ChristmasTree tree = new ChristmasTree(7);
tree.print();
tree.print();
tree.print();

Happy Holidays!!

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