Java supports three classes to operate on strings, String, StringBuffer and StringBuilder. The main difference between them is, String is immuatable, whereas StringBuffer & StringBuilder provides mutable object.
Basis | String | StringBuilder | StringBuffer |
---|---|---|---|
String Type | A String class always create an immutable string | It produces a mutable string | It provides another way of creating mutable string |
Thread Safe | It doesn’t ensure thread safety as it’s not synchronized | It is not thread safe | It is synchronized which assures thread safe enviroment |
Performance | It serves slower performance as it creates a separate object on each manipulation | It is not thread safe and this is why, it provides faster performance than StringBuffer | It is synchronized that is the reason it provides slower performance than StringBuilder |
Memory Wastage | Each time when manipulations are made to a string, a new object with applied changes created, despite the instance which always reference to original string | Operations are always performed on the original string object. It reflects the changes on that respective string. | Simmilar to StringBuilder, operations performed on a string alters the orginal version of the existing string. |
Memory allocation | It gets memory on String Constant Pool, even though it generated from String constructor as it first gets space on Heap but afterwards ends up with String pool | It uses Heap to store a string | It takes up space in Heap |
Purposed | Java 1.0 | Java 1.5 | Java 1.2 |
A string is a sequence of characters of object type that provides a way to work efficiently with this character array or string.
A string object is immutable which means that making any changes would not affect the respective string, instead a new string object comes into existence carrying those changes.
No matter how many operations are performed, the string reference variable always point towards original string.
In short ,
public class Main{ public static void main(String[] args) { String str ="Programmer"; str.concat("Bay"); System.out.println(" After Concatenation "+str); } }
Output:
Programmer
Explanation:
Since, the instance “str” would never change its reference therefore the output was Programmer.
str.concat(“Bay”) was creating “ProgrammerBay” which lead to a new object.
StringBuilder is used to create mutable strings and is growable in nature. It is not thread safe, that is why it provides faster performance than StringBuffer. However, when it comes to multithreading where multiple threads try to access an object, in such case, one should go with StringBuffer.
It has two primary methods, append and insert. Append adds a character sequence at the end each time whereas insert put a specific set of characters at specified location. It automatically grows larger as and when internal buffer overflows.
In other words,
public class Main{ public static void main(String[] args) { String str ="Programmer"; str.append("Bay"); System.out.println(" After Concatenation "+str); } }
Output:
ProgrammerBay
Explanation:
str.append(“Bay”) was creating “ProgrammerBay” and update the object to which str was referencing.
A way of having synchronized string object along with its operational methods . It is thread safe as each and every thread would sequentially access and perform the operations on the object using predefined methods. The only difference between String Buffer and String Builder is the thread safety.
In other words,
package com.company; class Example implements Runnable { String str = new String("Programmer"); @Override public void run() { for(int i =0;i<10000000;i++) { str.concat(" "); } } } public class Main { public static void main(String[] args) { Example obj = new Example(); Thread thread1 = new Thread(obj); long start = System.currentTimeMillis(); thread1.start(); try { thread1.join(); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.printf((end-start) + "ms"); } }
Output:
161ms
package com.company; class Example implements Runnable { StringBuilder str = new StringBuilder("Programmer"); @Override public void run() { for(int i =0;i<10000000;i++) { str.append(" "); } } } public class Main { public static void main(String[] args) { Example obj = new Example(); Thread thread1 = new Thread(obj); long start = System.currentTimeMillis(); thread1.start(); try { thread1.join(); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.printf((end-start) + "ms"); } }
Output:
48ms
class Example implements Runnable { StringBuffer str = new StringBuffer("Programmer"); @Override public void run() { for(int i =0;i<10000000;i++) { str.append(" "); } } } public class Main { public static void main(String[] args) { Example obj = new Example(); Thread thread1 = new Thread(obj); long start = System.currentTimeMillis(); thread1.start(); try { thread1.join(); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.printf((end-start) + "ms"); } }
Output:
255ms
This post was last modified on October 6, 2020