Java String interview Questions - 2

 What is the output of following code and Why ?

public class TestString {

 public static void main(String[] args) {
String str1 = "Hello";
       String str2 = new String("Hello");
       System.out.println(str1.hashCode() == str2.hashCode());
  }
}

Output: true

Explanation:






















Line 1: String str1 = "Hello";

Here String literal (object) is created in the String constant pool area of the heap memory. JVM see that it is string literal and there is no existing literal with that value in String constant pool, so it creates a new String literal with value "Hello" in the String constant pool. This is done by JVM for efficient usage of memory. The reference variable str1 refers(read have address of this String literal) to this String literal. 

Line 2: String str2 = new String("Hello");

Here as we are creating String object using new operator, JVM creates a new String object in heap with value "Hello". str2 refers to(or read have address of this newly created object in heap) to object in heap.


Line 3: System.out.println(str1.hashCode() == str2.hashCode());

Here we are calling hashCode() method on str1 and str2 and  comparing hashcodes of objects referred by str1 and str2 respectively.

Now because String class has overriden the hashCode() method of Object class from which it inherits and the overriden implementation in the String class calculates hashCode based on the value of String, hashCode of both the String objects will be same as both have same value.

Here is source code of hashCode() method from String class (JDK 17) and you can see that hashCode is calculated on the basis of value.

/**
* Returns a hash code for this string. The hash code for a
* {@code String} object is computed as
* <blockquote><pre>
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
* </pre></blockquote>
* using {@code int} arithmetic, where {@code s[i]} is the
* <i>i</i>th character of the string, {@code n} is the length of
* the string, and {@code ^} indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return a hash code value for this object.
*/
public int hashCode() {
// The hash or hashIsZero fields are subject to a benign data race,
// making it crucial to ensure that any observable result of the
// calculation in this method stays correct under any possible read of
// these fields. Necessary restrictions to allow this to be correct
// without explicit memory fences or similar concurrency primitives is
// that we can ever only write to one of these two fields for a given
// String instance, and that the computation is idempotent and derived
// from immutable state
int h = hash;
if (h == 0 && !hashIsZero) {
h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
if (h == 0) {
hashIsZero = true;
} else {
hash = h;
}
}
return h;
}


Java String Interview Questions - 1

What is the output of following Java code:


public class TestString {

 public static void main(String[] args) {

     String str1 = "Hello";

     String str2 = new String("Hello");

     System.out.print(str2 == "Hello");

 }

}

Explanation:




Line 1: String str1 = "Hello";

Here String literal (object) is created in the String constant pool area of the heap memory. JVM see that it is string literal and there is no existing literal with that value in String constant pool, so it creates a new String literal with value "Hello" in the String constant pool. This is done by JVM for efficient usage of memory. The reference variable str1 refers(read have address of this String literal) to this String literal. 


Line 2: String str2 = new String("Hello");

Here as we are creating String object using new operator, JVM creates a new String object in heap with value "Hello". str2 refers to(or read have address of this newly created object in heap) to object in heap.


Line 3:  System.out.print(str2 == "Hello");

When we compare two object references using '==' , we are comparing whether two object references are pointing to same object in memory or not. If two object references are pointing to same object in memory or in other words if two object references have addresses of same object in memory, then result of comparing two object references using '==' will return true and if two object references have address of two different memory locations then comparison will return false.


so str1 == str2 would have returned false as str1 has address of String object in String constant pool and str2 has memory address of String object in heap and of course as two addresses are different, result of comparison will be false.

As in our case, we are comparing str2 (which is reference to String object in heap) with String literal "Hello" using '==', it is apparently comparing memory address of the String in heap(4444) with memory address of the String  literal "Hello" in String constant pool(5555), which is of course not equal, so answer will be false.



Grep command and interesting things you can do with it

What is Grep ?

grep is a command line utility for searching plain text data sets for lines that match a regular expression. grep was developed originally for Unix operating system but later was available for all Unix like operating systems. 

grep stands for global regular expression print.




Which file types grep is compatible with ?

grep is compatible with a wide variety of file types, as long as the files contain text that can be searched for patterns using regular expressions.

Some common file types that can be searched with grep include:

Plain text files: These are simple text files with no special formatting or encoding.

Configuration files: These files are used to configure applications and services and often have specific syntax and formatting rules.

Code files: These files contain programming code written in various languages such as C, Java, Python, etc.

Log files: These files are used to store system logs and application logs and can be searched to find specific events or error messages.

HTML, XML, and other markup files: These files contain structured data and can be searched for specific tags, attributes, or values.

CSV and other delimited data files: These files contain tabular data separated by commas or other delimiters, and can be searched for specific values or patterns.

In general, any file that contains text can be searched with grep. However, grep may not work well with binary files or files that are encoded in a non-text format, such as images or audio files. In such cases, you may need to use specialized tools or libraries that are designed to work with those file types.

What is the syntax for grep command ?

grep [OPTIONS] PATTERN [FILE...]

OPIONS are various command-line options that can be used to modify the behavior of grep. Some common options include:

-i: Ignore case distinctions during the search.

-v: Invert the match; display all lines that do not match the pattern.

-n: Display the line numbers of the matched lines.

-c: Display only the count of matched lines.

-r: Search recursively in directories and their subdirectories.

PATTERN is the regular expression that you want to search for in the specified files.

FILE... is the name of the file(s) to search. If no file is specified, grep searches for the pattern in standard input.

What are the examples of Grep command ?

1. Searching for a string in a file

     grep "search text" file.txt

It will search file with name file.txt for any matching string "search text" in whole file and return lines which contains string "search text".

2. Searching for a string in multiple files.

    grep "search text" file1,txt file2.txt file3.txt

 It will search for files with names file1.txt, file2.txt, file3.txt for text "search text" and return lines with matching text.

3. Searching for a string in all files in a directory

    grep "search text" directory/*

  It will search all files under directory with name 'directory' and returns lines with matching text.

4. Searching for à string in all the files in a directory and its subdirectories.

  grep -r "search text" directory/

 It will search in files in a directory with name 'directory' and recursively under its subdirectories for text "search text" and return all matching lines.

5. Searching for a string and ignoring case.

   grep -i "search text" file1.txt

  It will search in file file1.txt for text "search text" ignoring case and return all matching lines. So, for example, if there is line which has "SEARCH TEXT" or "Search Text", those lines will also be returned.

6. Searching for a string and returning line numbers.

  grep -n "search text" file1.txt

  It will search file file1.txt for text "search text" and return all  lines having "search text" along with line numbers of the lines.

7. Searching for a string and only returning matching string.

  grep -o "search text" file1.txt

It will search in file file1.txt for "search text" and return for each matching line with "search text". 

8. Searching for a string and returning lines which does not contain the string

 grep -v "search text" file.txt

9. Searching for a string and returning only count of matching string

grep -c "search text" file.txt

10. Searching for a string and returning count of the number of occurrences of string.

grep -o "search text" file.txt | wc -l

How to use output of another command as input to search for grep command ?

Example1:

Suppose you have a command that generates some output, like ls -l, and you want to search that output for files that end with ".txt". You can pipe the output of ls -l into 'grep' like this:

ls -l | grep "\.txt$"

In this case, ls -l generates output and pipes it into grep. The pattern \.*txt$ will then be applied to the input that grep receives from ls -l. The $ at the end of the pattern means "end of line", so this pattern will match any line that ends with ".txt".

So, if no file is specified, grep searches for the pattern in standard input, which means you can pipe the output of another command into grep to search for a pattern within that output.

Example2:

Suppose under the current directory and its subdirectories, you want to search for all the files which has .log extension and then for each file that has .log extension, you want to execute grep to search for a text 'search text', then you need to execute following command:

find . -name "*.log" -exec grep -H 'search text' \{\} \

It will print the name of the file along with each matching line that contains the 'search text'.

Here's how the command works:

find . -name "*.log" searches for all files under the current directory and its subdirectories with a .log extension.

-exec is a flag that tells find to execute a command on each file that matches the search criteria.

grep -H 'search text' {} is the command that gets executed for each file that matches the search criteria. grep is a command that searches for patterns in text files. The -H flag tells grep to print the filename along with each matching line.

The \{\} is a placeholder that find replaces with the name of each file that matches the search criteria.

So when you run this command, find searches for all files with a .log extension under the current directory and its subdirectories, and for each file that matches the search criteria, it executes the grep command to search for the pattern "search text". The output shows the filename along with each matching line that contains the pattern.

Example 3:

cat file.txt | grep "pattern"

cat can be used to display the contents of a file, and grep can be used to filter the output based on a pattern. 

Example 4:

cat file.txt | grep "pattern" | awk '{print $1}'

awk is a powerful text processing tool that can be used to filter and manipulate text data. grep can be used to filter the input, and awk can be used to perform additional processing. 

Example 5:

cat file.txt | grep "pattern" | sed 's/foo/bar/g'

sed is another text processing tool that can be used to manipulate text data. grep can be used to filter the input, and sed can be used to perform additional processing.

This command uses grep to filter the input based on a pattern, and then uses sed to replace all occurrences of "foo" with "bar".

Example 6:

ps -ef | grep "process name"

ps can be used to list all running processes, and grep can be used to filter the output based on process name.

Can we use grep to search text in compressed file, like file compressed using gzip ?

grep does not work with compressed files compressed with gzip. To search text in files compressed with gzip, you need to use zgrep command line utility.

Example:

zgrep "search text" file.gz

Thanks for reading. If you enjoyed reading the article then please Subscribe to the blog.

How to get current date time with Java 8

 In this quick tutorial, we will see, how to get current date time using Java 8.


Java 8 had come up with new set of classes for date and time under java.time package, which are :

-  java.time.Instant

- java.time.ZonedDateTime

- java.time.OffSetDateTime

- java.time.LocalDateTime

Let us see how we can get current date and time using these classes and how they are different from each other.

Using Instant 

Instant represents a moment. For example, if World cup is starting at certain moment, it is exact that moment for everyone living in any part of world. If world cup is in Australia, then people in India can say that ,world cup started at different time than what what was time in Australia but it started at exact same moment on timeline for people of Australia as well as India. 

Using Instant, we can get the exact moment on timeline which is independent from time zones.

which in other words means that if two Instant objects are created at the same moment in any part of world, they will have exactly same value.

Instant represents date time in UTC(coordinated universal time), so it does not consider specific Zone and it is number of nanoseconds elapsed since epoch or since 1970-01-01T00:00:00Z. It is similar to GMT(Greenwich mean time).

All date times for specific Zones are calculated relative to UTC. 

For example : 
- A time in UTC (zone) itself, UTC + 0 is indicated by a Z( Z from Zulu time)
- Countries like Ireland, Portugal, Ghana follows UTC time zone, which means UTC + 0
- Japan follows UTC+9
- Barbados follows UTC-4

For complete list for all countries, you can check List of Countries with UTC time offsets

For our back end calculations in Java, we use Instant. For example, If we are running a job and want to calculate the time for next run we would use Instant. 

The reason of using Instant are:

Time Consistency Across Servers

Using UTC ensures that backend operations yield consistent results regardless of the specific time zone of the server, enhancing system reliability.

Simplified Daylight Saving Time Management

UTC does not adhere to daylight saving time adjustments, offering a straightforward solution for managing time operations consistently.

Log and Audit Integrity

When logging events or auditing actions, using UTC timestamps ensures consistency and ease of analysis, as there is no need to account for different time zones in log records.

Avoids Time Zone Confusion: 

When dealing with multiple time zones, using UTC can help avoid confusion and errors that can arise from converting times between various time zones. Developers can perform calculations and comparisons without worrying about different time zone conversions.

Now coming back to current date time using Instant, we need to use now() method as below :
Instant instant = Instant.now();
System.out.println("Current Date Time using Instant:" + instant);
Output:
Current Date Time using Instant:2021-01-09T22:25:06.385917300Z

Using ZonedDateTime

If you want to know date time, in your time zone, at a particular moment( represented by Instant) you can use ZonedDateTime.

You can either adjust the instant created above to get the ZonedDateTime like below :

Adjusting Instant object :

System.out.println("Using instant.atZone():" + instant.atZone(ZoneId.of("Europe/Amsterdam")));
Output:
Using instant.atZone():2021-01-09T23:25:06.385917300+01:00[Europe/Amsterdam]
This gives me exact date time in Amsterdam.

Using now(ZoneId zoneId) :

Alternatively you can use factory method now(ZoneId zoneId) defined in ZonedDateTime class itself like below:
System.out.println("Using ZonedDateTime.now(zoneId):" + ZonedDateTime.now(ZoneId.of("Europe/Amsterdam")));
Output:                                                                       Using ZonedDateTime.now(zoneId):2021-01-09T23:25:06.408922700+01:00[Europe/Amsterdam]

Using now() :

And there is one more option where in you can use factory method now() of ZonedDateTime class. However you must know that now() uses the default time zone of your JVM, which is subject to change, so better always pass zoneId.
System.out.println("ZonedDateTime with now():" + ZonedDateTime.now());
Output:                                                                       Using ZonedDateTime.now():2021-01-09T23:25:06.414919900+01:00[Europe/Berlin]
Another variant of now() is like below for using default time zone using ZoneId.systemDefault() as ZoneId.
System.out.println("Using ZonedDateTime.now(ZoneId.systemDefault())" + ZonedDateTime.now(ZoneId.systemDefault()));
Output:                                                                       Using ZonedDateTime.now(ZoneId.systemDefault()):2021-01-09T23:25:06.414919900+01:00[Europe/Berlin]

ZonedDateTime supports Day Light Savings

ZonedDateTime uses ZoneRules to determine how an offset varies for a particular time zone in case of Day light saving.

Lets take an example. Day light saving in Netherlands in 2021 is going to start from March 28, 2:00 AM and will end on October 31, 3:00 AM

Let us first try to see date time before(by 1 hour) Day light saving starts, i.e. at 1 AM
System.out.println("ZonedDateTime.of() before DLS: " + ZonedDateTime.of(2021, 3, 28, 1, 0, 0,0, ZoneId.of("Europe/Amsterdam")));
Output:
ZonedDateTime.of() before DLS: 2021-03-28T01:00+01:00[Europe/Amsterdam]

As you can see, it returned the time which we have asked for i.e. 1 AM and offset is of +1:00

Now let us try to see date time at the time when Day light saving is going to start i.e. at 2 AM.
System.out.println("ZonedDateTime.of() DLS start: " + ZonedDateTime.of(2021, 3, 28, 2, 0, 0,0, ZoneId.of("Europe/Amsterdam")));
Output                                                               ZonedDateTime.of() DLS start: 2021-03-28T03:00+02:00[Europe/Amsterdam]

As you can see , ZonedDateTime API automatically adjusted the time and returned time which is 1 hour ahead i.e. 3 AM instead of 2 AM and also now Offset is set to +2:00.

Using OffsetDateTime

OffsetDateTime represents a moment in date time which is some duration ahead(+) or behind(-) the UTC or in other words with offset from UTC without a Time ZoneId such as "Europe/Amsterdam".

You can use ZoneOffset class to represent offset in hours, hours: minutes or hours: minutes: seconds.

So if the OffSet is zero, then OffsetDatTime represents Instant, which is in UTC.
System.out.println("Using OffsetDateTime.now():" + OffsetDateTime.now());
Output:                                                                       Using OffsetDateTime.now():2021-01-09T23:25:06.415920100+01:00

Using LocalDateTime

LocalDateTime gives you date time without any offset(from UTC) information or any Zone information, which in other words means it can not represent moment on the timeline.
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime is:" + localDateTime);
Output:
localDateTime is:2021-01-09T23:25:06.416918700

Summary

- There are multiple way you can get hold of current date time using Java 8 API depending upon your requirements.
- Instant gives you moment on timeline and gives you date time in UTC and does not consider time zone.
- Any two instances of Instant created at same moment in any part of world will give you same objects, which means they represents the same moment on the timeline.
- You can use ZonedDateTime class for date time with Offset from UTC and Zone information.
- You can use OffsetDateTime to get date time with OffSet from UTC.
- You can use LocalDateTime ,if you want to get date time as shown on your clock.

Static Nested Classes Java

In Java, it is possible to define a class within another class. Class defined within another Class is called a Nested Class.


Nested class is treated as a member of the Outer class because it is also defined within the Outer class like its other members(variables or methods).

public class OuterClass {
    class NestedClass {

    }
}

Although Outer class can be declared only either as public or package private(no access modifier) but Nested classes can have any of the access modifier public, private, protected or package private(no access modifier), reason being , nested class is also just like a member of the Outer class, so just like you can have public, private ,protected or package private instance variables or methods, you can have these access modifiers for nested classes as well.

Now if you define your nested class as static, then they are called static nested class and if you don't define them as static then they are called non static nested classes or Inner classes. So Nested classes are broadly of two types :

- Static Nested Classes

- Inner Classes   

In this post, we will discuss static nested classes.

Static Nested Class :

They are just like any other Java class which are defined with a static modifier within a Outer class for the packaging convenience and from packaging convenience I mean that instead of creating another top level class we packaged this nested class within another class as this nested class made sense only in the context of enclosing Outer class. We will see example later.
public class OuterClass {
    public static class NestedClass {

    }
}

Rules for static nested class as a static member of Outer class

Rules for instantiating static nested class

Because static nested classes are static ,so just like the static methods and variables they follow the rules which static members within a class follows. So just like static methods and variables, they belong to their Outer class and not to the instance(s) of the Outer class. So you don't need to instantiate OuterClass first but you just use <outer class><dot><nested class> syntax to instantiate the nested classes as in below example.
public class TestClass {
    public static void main(String[] args) {
        OuterClass.NestedClass nestedClass = new OuterClass.NestedClass();
    }
}

Rules for accessing the Outer class members from static nested class

Static nested class being static, can only access the static members of its outer class. It does not have access to the instance members of the Outer class. This makes sense again, if you think just from static perspective. Any static method of our class in general can only access the static variables or static methods only, so the same concept is applied for static nested classes as well, because they are also the static members of the Outer class from Outer class perspective.
public class OuterClass {
    private static String x;
    private String y;

    public static class NestedClass {
        public void test() {
            // x is accessible
            System.out.println(x);

            // y is not accessible here and it will give compiler time error 
            // "No static field 'y' can not be referenced from static context.
            System.out.println(y);
        }
    }
}
You might have noticed that test() method itself is not static but still the compiler warning says "can not be referenced from static context", this is because although test() method is not a static method but still the class in which it has been defined as , is static, so from OuterClass perspective "y" which is not a static member of OuterClass is being referred from within it's static member NestedClass.

Other than that from its own existence perspective, they are just like any normal Java classes, which means :

- You can create their objects(By using <OuterClass><dot><NestedClass> syntax).
- You can have instance variables within them.
- You can have instance methods within them.
- You can have static methods in them.
- You can extend them.
- You can declare them final.

Only difference from top level java class is that it can be declared static and it can have any of the access modifier which means public, package private, protected or private.

So to conclude this section, you need to see static nested classes from two perspective :

- As a static member of the Outer class and rules for accessing it(nested class) being a static member     And rules for accessing Outer class members.
- As a normal Java class which is just packaged within another class.

What is the use of Static nested Classes ?

1. Packaging Convenience and as Helper classes

In general, we use nested class when the class is not required to be used anywhere else other than in the class it is part of. For example we can define helper classes using nested static classes. And if they need to be accessed also from within Outer class only, we can declare static nested class as private, so that it is invisible to the outside world.

For example: 

1. If we see java.util.Collections class in JDK, you can find lots of private nested classes like:

SetFromMap
ReverseComparator
CopiesList

As these classes serve only to Collections class, are not being used from anywhere else in JDK and does not use any instance variable or method of the outer Collection class, they have been kept as private and nested static classes.

2. Static nested classes specially should be used(instead of inner classes) when you don't want to use enclosing class's instance members in nested class but want to keep Outer class and Nested class together for packaging convenience. For example, in the Builder Pattern that we discussed in one of previous post, Builder is created as static nested class. This builder does not use/call any of the Outer class instance variable/method but as we know that this builder makes sense only in context of Student class, so we packaged Student and its builder together.

And we can instantiate this static nested builder without using the instance of the Outer class as below:
Student.StudentBuilder studentBuilder2 = new Student.StudentBuilder("2",                                                                                                     "Sachin", "Tendulkar").withAge("47");
3. They are very useful for creating Request and Response type of classes for your restful services as you can easily map them to the Json structure.
public class Employee {
    private String name;
    private String age;

    public static class Address {
        private int houseNumber;
        private String streetName;
    }
}

2. Better Readability and Maintainability 

It leads to more readable and maintainable code because you keep closely used classes together at one place instead of spreading it across in multiple top level classes.

Summary

- Nest a class inside another class as a static nested class, when the class you are going to write is going to be used only within that class or in its context.
 - Make it static because you don't need access to the instance members of Outer class. If you need access then go for Inner classes.
- Only nested classes can be declared as static. Top level classes can not be declared as static.
- Static nested classes can be declared public, protected, package private or private. Top level classes can only be public or package private.
- If a static nested class is declared as public, but Outer class is package private, then you can access nested class also within that package only because static nested class can only be accessed by using class name of the Outer class and if Outer class is not visible then static nested class will not be visible even if it is public.
- Nested static classes are like static members of the Outer class and follows the rules of static within Outer class.
- Use them as helper classes for better readability or for request response for rest service.

Thank you for reading. If you any question or suggestion to add further in this post, you can let me know in comments section.

Builder Design Pattern

Hello Friends,

In this tutorial, we will discuss Builder design pattern. 


Key topics we are going to discuss are :

- Which category Builder Design Pattern falls in ?
- What problem builder Pattern is solving or when to use Builder pattern?
- Builder Pattern 
- Builder Pattern Example
- Advantages of Builder Pattern
- Disadvantages of Builder Pattern

Which category Builder Design Pattern falls in ?


Builder pattern falls under Creational design patterns category, as it deals with the creation of object(s).Please note that Builder design pattern that I am going to describe here is not GOF design pattern but the one suggested by Joshua block in Effective Java, as I personally see this pattern used for more often or more practical than the one suggested by GOF.

What problem builder Pattern is solving or when to use Builder pattern?


In nutshell, you should use Builder design pattern when :
- You have a class , which has some mandatory fields and a some optional fields, which in other words means that your object can be constructed in various ways as per requirements. Although you are free to use it with a class with all mandatory fields as well when number of fields are too many(usually more than four is good candidate).
- You want objects of your class to be immutable, which means once objects are instantiated there state can not be changed after that.

Now lets discuss these points in more detail.

You have a class with some mandatory and some optional fields :

What is the problem with having optional fields.

Let us say you have below Student class with mandatory and optional fields and have a constructor with all the fields.
package com.blogspot.javasolutionsguide;

public class Student {
    //mandatory fields
    private final String id;
    private String firstName;
    private String lastName;                                                                                                                                            //optional fields
    private String age;
    private String houseNumber;
    private String streetNumber;

    public Student(String id, String firstName, String lastName, String age, String houseNumber, String streetNumber) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.houseNumber = houseNumber;
        this.streetNumber = streetNumber;
    }

    public String getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getAge() {
        return age;
    }

    public String getHouseNumber() {
        return houseNumber;
    }

    public String getStreetNumber() {
        return streetNumber;
    }
}

Now, say the client of this code might want to create instance of Student with 

- Only Mandatory fields
- All the Mandatory as well as optional fields
- Mandatory fields and one or more of the optional fields

Then the constructors for above scenarios will look like as below :
//Only Mandatory fields                                                       Student student2 = new Student("201", "firstName2", "surName2", null, null, null);
//All the Mandatory as well as optional fields                               Student student1 = new Student("101", "firstName1", "surName1", "16", "11", "2");
//Mandatory fields and one or more optional fields                           Student student3 = new Student("301", "firstName3", "surName3", "20", null, null);
Student student4 = new Student("301", "firstName4", "surName4", "20", "22", null);
Now what is the problem with above constructors?

Actually there are multiple problems, like 
- Client code has to unnecessarily pass null for all optional fields.
- Code readability is not good. As the number of parameters grow, it becomes difficult and error prone for client code to understand what needs to be passed at which position and later to read for the person who is going to maintain the code.
- When adjacent parameters are of same data type, you might accidently exchange their values which will go unnoticed at compile time but create some severe bug at run time. For example, developer can accidently interchange values for age and houseNumber.

So What can you do to solve these problems ?

Probably we can have look at the Telescoping constructor pattern.

In Telescoping constructor pattern, we create multiple constructor overloads starting with one with all mandatory fields and then with one optional field and then with two optional fields and so on until we have constructor with all fields.

Each constructor calls another constructor with one more optional field and passes the default value for the optional field(can be null or any other default you want to set) until the last constructor with all optional fields is called.
package com.blogspot.javasolutionsguide;

public class Student {

    //Mandatory fields
    private String id;
    private String firstName;
    private String lastName;

    //Optional fields
    private String age;
    private String houseNumber;
    private String streetNumber;

    public Student(String id, String firstName, String lastName) {
        this(id, firstName, lastName, "0");
    }

    public Student(String id, String firstName, String lastName, String age) {
        this(id, firstName, lastName, age, "0");
    }

    public Student(String id, String firstName, String lastName, String age, String houseNumber) {
        this(id, firstName, lastName, age, houseNumber, "0");
    }

    public Student(String id, String firstName, String lastName, String age, String houseNumber, String streetNumber) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.houseNumber = houseNumber;
        this.streetNumber = streetNumber;
    }
}

Now let us see which problems telescoping constructor solved :

- Client code no longer has to pass null for all the optional fields as well.
- From client code perspective, readability is better.

But telescoping constructors comes with its own problems:

- What if more optional fields are added in Student class in future, then for each new field another constructor needs to be introduced.
- Still you need to carefully see all overloads of the constructor and choose the one which suits your requirement.
- Still if you have say age and streetNumber but houseNumber is not available, then you need to instantiate Student class like below, so still client need to pass in null value for optional field.
Student student = new Student("101", "firstName", "lastName", "35", null, "3");

- And still there is possibility of getting exchange of values of same data type, when the number of optional fields are too many.

We will see how builder pattern solves these problems later but for now let us discuss the other aspect which makes a case for using builder pattern.

You want objects of your class to be immutable :

If you don't want state of your object to get changed once it has been created(and of course it has lots of fields), you can use build pattern, as builder pattern makes sure your object is immutable once it is created.

Advantages of Immutable classes :
- They are more reliable as it is known that their state is not going to change after creation. 
- They are inherently thread safe and don't need any synchronization.
- They make great candidates to be used as a key of a HashMap or to be put in a HashSet.

Now let us see implementation of Builder pattern by taking example of our Student class. 

Builder pattern


- In builder pattern , you leave the responsibility of creating object or instantiating your class to Builder which is another class which has exactly same number of fields as your class whose objects builder is going to build.

- As your builder class is going to be used only for creating objects of your class and is not going to be used elsewhere, it is defined as static nested class within your class.

- You provide a builder's constructor with only mandatory fields and then you provide methods(mutators) in builder to set the remaining optional fields. You can chain these methods as each of these method again returns Builder. Note that till now we are talking only about using builder constructor and using methods to set other optional fields and all these are still part of Builder object and we have not yet created actual Student object, so we are not concerned about immutability yet.

So in terms of code, we are here :
Student.StudentBuilder studentBuilder2 = new Student.StudentBuilder("2",                                                           "Sachin", "Tendulkar").withAge("47");
- Now all we need to do is call build() method of our builder on the created builder instance like below :
studentBuilder2.build()
which in turn calls private constructor of the Student class and passes "this" reference which is reference to the builder which is calling build() method. 
public Student build() {
     return new Student(this);
}
In the constructor, values are copied from builder to the Student instance variables and a complete immutable student object is created.
private Student(StudentBuilder studentBuilder) {                                            
    id = studentBuilder.id;                                                            
    firstName = studentBuilder.firstName                                            
    lastName = studentBuilder.lastName;                                                
    age = studentBuilder.age;                                                        
    houseNumber = studentBuilder.houseNumber;                                        
    streetNumber = studentBuilder.streetNumber;                                
}

Builder pattern example

package com.test.builder;

public class Student {
    //Mandatory fields
    private final String id;
    private final String firstName;
    private final String lastName;

    //Optional fields
    private final String age;
    private final String houseNumber;
    private final String streetNumber;

    private Student(StudentBuilder studentBuilder) {
        id = studentBuilder.id;
        firstName = studentBuilder.firstName;
        lastName = studentBuilder.lastName;
        age = studentBuilder.age;
        houseNumber = studentBuilder.houseNumber;
        streetNumber = studentBuilder.streetNumber;
    }

    public String getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getAge() {
        return age;
    }

    public String getHouseNumber() {
        return houseNumber;
    }

    public String getStreetNumber() {
        return streetNumber;
    }

    public static class StudentBuilder {
        //Mandatory fields
        private final String id;
        private final String firstName;
        private final String lastName;

        //Optional fields
        private String age;
        private String houseNumber;
        private String streetNumber;

        public StudentBuilder(String id, String firstName, String lastName) {
            this.id = id;
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public StudentBuilder withAge(String age) {
            this.age = age;
            return this;
        }

        public StudentBuilder withHouseNumber(String houseNumber) {
            this.houseNumber = houseNumber;
            return this;
        }

        public StudentBuilder withStreetNumber(String streetNumber) {
            this.streetNumber = streetNumber;
            return this;
        }

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

    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", age='" + age + '\'' +
                ", houseNumber='" + houseNumber + '\'' +
                ", streetNumber='" + streetNumber + '\'' +
                '}';
    }
}

and here is the test class :
package com.blogspot.javasolutionsguide;

public class TestStudentBuilder {
    public static void main(String[] args) {
        Student.StudentBuilder studentBuilder1 = new Student.StudentBuilder("1",                                              "Gauarv", "Bhardwaj");
        System.out.println(studentBuilder1.build());

        Student.StudentBuilder studentBuilder2 = new Student.StudentBuilder("2",                                             "Sachin", "Tendulkar").withAge("47");
        System.out.println(studentBuilder2.build());
    }
}

and here is the output:
Student{id='1', firstName='Gauarv', lastName='Bhardwaj', age='null', houseNumber='null', streetNumber='null'}
Student{id='1', firstName='Sachin', lastName='Tendulkar', age='47', houseNumber='null', streetNumber='null'}

Advantages of Builder Pattern :


- Client code is much more clean and readable. If we want to create object only with the mandatory fields ,we can just create builder instance with mandatory fields and then call build() method which will return us the Student object with only mandatory fields, however if we want to create Student object with some optional fields we can call respective methods like withAge() or withHouseNumber() and get Student object with all these fields as well. So we are not forcing client code to pass unnecessarily null values for the optional fields.
- Problem with getting values exchanged is also resolved as optional fields can be added by calling their respective methods which have clearly defined names.
- Object created using Builder pattern is immutable, as there are no setters in the Student class and also the constructor is private, so the only way to create Student object is via builder.

Disadvantages of Builder Pattern :


- Disadvantage is that you have to write lot of extra code for Builder class and as and when you need to add more fields, you need to add those fields both to your Student class as well as to your builder class. This is one of the reason that you should keep your Builder class within your class to be built as static nested class so that you don't miss to add new field to builder as well .

Overall better code readability and immutability that Builder patter offers overweighs disadvantages it has, in my opinion.

Thank you for reading. Let me know, if you have any questions in comments section.

How to convert Array to List in Java

Hello Friends,

In this tutorial, we will learn, various ways in which we can convert an array to a List. 

How to install Apache Web Server on EC2 Instance using User data script

Hello Friends,

In this tutorial, we will see how we can install Apache Web Server on EC2 instance using user data script.


How to Install Maria DB, create Database and Execute Queries

Hello Friends,

In this tutorial,we will see :

1. How to Install Maria DB
2. How to connect to Maria DB,Create Database and Execute Queries

What is @Qualifier annotation in Spring and why it is used


In this tutorial, we will explore the @Qualifier annotation of Spring framework.

1. What does @Qualifier annotation do
2. @Qualifier examples