Differences between String, StringBuffer and StringBuilder in Java

It is very important question of core java interview. Most of interviewers ask about difference between String, StringBuffer and StringBuilder and also where we should we use what? So in this article I will explain about these important classes and differences between them. First of all we know String is one of the most important class in java and String is immutable and final class in java. This means every modification in String creates a new string object like trim(), toUpperCase(), toLowerCase() etc. String object cached in String Pool memory in java. So in a large application we should always care about creating the String object using new keyword, it always create new object instead of using cached object of same string value. While working on a large application, you work with heavy usage of String but if you do profiling of your application, then you will find that String is the one of the class which creates lots of garbage because of many temporary String objects created in program.

In java there two more classes available for string manipulation. These classes are StringBuilder and StringBuffer. In java StringBuilder with new features added in to it as of JDK 5 but StringBuffer is old class. These two classes solve issues related string class.

String class in Java

Lets see some properties about these classes first before difference between them.

1. String is immutable in Java.
In java, string class is immutable because String objects are cached in String pool. Immutable means unmodifiable or unchangeable, means once string object is created its data or state can't be changed but a new string object is created. Immutability nature of String class provides lot of benefit, In HashMap its hashcode value is cached which makes it a faster hashmap key. String class's final nature provide benefit to safely shared in to multiple threads without need of any synchronization.

2. In java String objects we can create in two ways one is creating new keyword with construct and other created by using literal. If we create string object by using literal then this value cached to string pool whenever required another sting with same value it assign same cached object of string instead of creating new object.

For example .
String str1= "java";
String str2= "java"; 

String immutable

3. Here we represent string in double quotes "java", they are referred as String literal and created in String pool. So, when you compare two String literals using equality operator "==" it returns true because they are actually same instance of String.

4. When we use "+" operator for two or more strings concatenation then it creates new string after concatenation of all given values of string, internally "+" operation is implemented using either StringBuffer or StringBuilder.

5. String class in java overrides equals() and hashcode() method of object class because of two Strings should be consider equal if they contain exactly same character. In java collection there are many sorted collections like SortedSet, SortedMap etc. and for these collections string is used as key so it must be consistent with compareTo() method for String.

6. toString() method of object is also overrides by string class to provides String representation of any object and its recommended for other class to implement this and provide String representation.

7. String is represented using UTF-16 format in Java.

8. String object can be created by multiple ways such as char array, byte array, from another string, from StringBuffer and from StringBuidler. String class provides many more overloaded constructors of supporting mutliple to way to create string object.

Problem with String
The main problem with String consumes large space if it is not used properly. This problem of string is due to immutability nature of String. Any modification in string like trim(), toUpperCase(), toLowerCase(), getting sub-string and concatenation with other string etc. Since String is an immutable class, every time a new String is created and older one is discarded which creates lots of temporary garbage in heap. Let see with example as below

//To declare a new String object
String str1 = "Hello";

//To declare another String object
String str2 = "Java";

//When we concatenate two string objects then it will create a new object in memory.
str2 = str2 + str1;

Differences between String, StringBuffer and StringBuilder in Java

String vs StringBuffer

String is immutable while StringBuffer is mutable. It means you can not modify a String object but you can modify StringBuffer object after creating it without creating any new object. This mutable nature of StringBuffer class solve the problems generated by immutable nature of Strig.

We can convert StringBuffer to String class by using toString() method.

Below is the example of String and StringBuffer:

//To declare a new String object
String str1 = "Hello";
String str2 = "Java";
//When we concatenate any new value to string then it creates a new 
object in memory.
str2 = str1 + str2;

Solve the space problem with using StringBuffer:

//To declare a StringBuffer object
StringBuffer sb = new StringBuffer("Hello");
sb.append(" Java");

StringBuilder vs StringBuffer

StringBuilder one more class added to JDK as of version 5 of java. But this class also provide functionality of String and StringBuffer but there are following points that makes StringBuilder different from StringBuffer and String:

All method of StringBuffer class are synchronized because of make it thread-safe, but same time slow. But StringBuilder is not synchronized. In java 5 StringBuilder is a copy of StringBuffer but without synchronization. Try to use StringBuilder whenever possible it performs better in most of the cases than StringBuffer class.

If you want to concatenate two strings by using "+" then "+" operation is internally implemented using either StringBuffer or StringBuilder in Java.

Below is the example of StringBuilder and StringBuffer:

//To declare a new StringBuffer object
StringBuffer buffer = new StringBuffer("Hello");
buffer.append(" Java");

//To declare StringBuilder object
StringBuilder builder = new StringBuilder("Hello");
builder.append(" Java");

If you see above example of StringBuilder and StringBuffer, you will find that they are exactly similar and all API methods applicable to StringBuffer are also applicable to StringBuilder in Java.

Java provides three classes StringBuffer, String and StringBuilder with different purposes. But these classes are used to manipulate string. There following point we found to make it these differ in functionalities for same target.

  • String is immutable in nature while StringBuffer and StringBuilder is mutable.
  • StringBuffer is synchronized while StringBuilder is not.
  • StringBuilder is faster than StringBuffer becuase of StringBuffer is thread-safe.
  • Concatenation operator "+" for String is internally implemented using either StringBuffer or StringBuilder.
  • Use String if immutability is required.
  • Use Stringbuffer if you need mutable with thread-safety
  • Use StringBuilder if you require mutable without thread-safety.