The intention is to abstract steps of construction of objects when there are lot of parameters and to provide thread safety at the time of object creation. You will have Class and ClassBuilder(static inner class) which has same parameters as Class, setters for parameters and a build method. The setter methods in ClassBuilder helps to carry validation over parameters before the object for Class gets created in build method

Why builder Pattern?
If there are many attributes in the class and object is created over several calls it may be in an inconsistent state partway through its construction. To address this builder pattern is introduced. If Object Creation should be delayed until all the validation of class attributes are performed builder pattern addresses the need.

If there are 2 attributes to a Class then we can create 2^N Constructor based on the two attributes. This Results in Boiler plate code. What if the number of attributes keeps increasing over a period of time.

Report.java

import java.util.InvalidPropertiesFormatException;

public class Report {
    private String reportName;
    private String reportFormat;

    private Report(){}

    public static ReportBuilder getReportBuilder(){
        return new ReportBuilder();
    }


    @Override
    public String toString() {
        return "Report{" +
                "reportName='" + reportName + '\'' +
                ", reportFormat='" + reportFormat + '\'' +
                '}';
    }

    public static class ReportBuilder {
        private String reportName;
        private String reportFormat;

        private ReportBuilder(){}

        public ReportBuilder setReportName(String reportName) {
            this.reportName = reportName;
            return this;
        }

        public ReportBuilder setReportFormat(String reportFormat) {
            this.reportFormat = reportFormat;
            return this;
        }

        public Report build() throws InvalidPropertiesFormatException {
            if(this.reportFormat == "CSV"){
                throw new InvalidPropertiesFormatException("Format Not Supported");
            }

            if(this.reportName.length() < 10){
                throw new InvalidPropertiesFormatException("Name should be greater than 10");
            }

            //Object for Report should not be created before validation is completed as above
            Report objReport = new Report();
            objReport.reportName = this.reportName;
            objReport.reportFormat = this.reportFormat;
            return objReport;
        }
    }
}

BuilderPatternClient.java

import java.util.InvalidPropertiesFormatException;

public class BuilderPatternClient {
    public static void main(String[] args) throws InvalidPropertiesFormatException {
        Report objReport = Report.getReportBuilder()
                .setReportFormat("PDF")
                .setReportName("Monthly Transactions")
                .build();

        System.out.println(objReport);
    }
}

Output

Report{reportName='Monthly Transactions', reportFormat='PDF'}

What is Telescoping Constructor Pattern?
In Java, there is no support for default values for constructor parameters. As a workaround, a technique called “Telescoping constructor” is often used. A class has multiple constructors, where each constructor calls a more specific constructor in the hierarchy, which has more parameters than itself, providing default values for the extra parameters.

We’ve all at some point encountered a class with a list of constructors where each addition adds a new option parameter

Pizza(int size) { ... }        
Pizza(int size, boolean cheese) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }

Disadvantage
This is called the Telescoping Constructor Pattern. The problem with this pattern is that once constructors are 4 or 5 parameters long it becomes difficult to remember the required order of the parameters as well as what particular constructor you might want in a given situation.

One alternative you have to the Telescoping Constructor Pattern is the JavaBean Pattern where you call a constructor with the mandatory parameters and then call any optional setters after:

Pizza pizza = new Pizza(12);
pizza.setCheese(true);
pizza.setPepperoni(true);
pizza.setBacon(true);

The problem here is that because the object is created over several calls it may be in an inconsistent state partway through its construction. This also requires a lot of extra effort to ensure thread safety.

The better alternative is to use the Builder Pattern.

public class Pizza {
  private int size;
  private boolean cheese;
  private boolean pepperoni;
  private boolean bacon;

  public static class Builder {
    //required
    private final int size;

    //optional
    private boolean cheese = false;
    private boolean pepperoni = false;
    private boolean bacon = false;

    public Builder(int size) {
      this.size = size;
    }

    public Builder cheese(boolean value) {
      cheese = value;
      return this;
    }

    public Builder pepperoni(boolean value) {
      pepperoni = value;
      return this;
    }

    public Builder bacon(boolean value) {
      bacon = value;
      return this;
    }

    public Pizza build() {
      return new Pizza(this);
    }
  }

  private Pizza(Builder builder) {
    size = builder.size;
    cheese = builder.cheese;
    pepperoni = builder.pepperoni;
    bacon = builder.bacon;
  }
}

Note that Pizza is immutable and that parameter values are all in a single location. Because the Builder’s setter methods return the Builder object they are able to be chained.

Pizza pizza = new Pizza.Builder(12)
                       .cheese(true)
                       .pepperoni(true)
                       .bacon(true)
                       .build();

This results in code that is easy to write and very easy to read and understand. In this example, the build method could be modified to check parameters after they have been copied from the builder to the Pizza object and throw an IllegalStateException if an invalid parameter value has been supplied. This pattern is flexible and it is easy to add more parameters to it in the future. It is really only useful if you are going to have more than 4 or 5 parameters for a constructor. That said, it might be worthwhile in the first place if you suspect you may be adding more parameters in the future.

Factory Patterns vs Builder Pattern
Consider a restaurant. The creation of “today’s meal” is a factory pattern, because you tell the kitchen “get me today’s meal” and the kitchen (factory) decides what object to generate, based on hidden criteria.

The builder appears if you order a custom pizza. In this case, the waiter tells the chef (builder) “I need a pizza; add cheese, onions and bacon to it!” Thus, the builder exposes the attributes the generated object should have, but hides how to set them.