Scientech Easy StringBuffer Class in Java | Example Programs | Scientech Easy

Wednesday, May 15, 2019

StringBuffer Class in Java | Example Programs

StringBuffer Class in Java


You have learned in the previous tutorial that string is fixed-length, immutable and cannot be modified. i.e, Once we create a String object, we cannot change its content.

To overcome this, we got another class StringBufferIt is also present in the java.lang package similar to the string class. It provides the same functionality as String class but there are also additional features in StringBuffer class. It represents a growable nature and mutable. It means that Once we create a StringBuffer class object, we can perform any required changes in the object. i.e, its data can be modified.

That's why StringBuffer class objects are mutable in Java. The methods of string buffer class can directly manipulate data inside the object. StringBuffer class method is synchronized. Therefore, it is a thread-safe class but it is a slower than string.

StringBuffer Class Constructor in Java


Before going to discuss three constructors, we have to understand a very important small point.
StringBuffer class in Java
In the above fig 1, we have created a string object with content "Hello". We have already learned that once we create a string object with content, there is no chance to change its content because the string object is immutable. That means if we cannot change its content, the length of content "Hello" is fixed i.e. 5 and its capacity is also 5 because we cannot add new characters. Therefore, in the string, the terminology length and capacity both are the same. So, string never uses the terminology "capacity".  

But in the case of StringBuffer, there is a small difference between length and capacity.
Capacity: The total number of characters hold in the StringBuffer object is called capacity.
Length: The number of characters already present in the StringBuffer object is called length.

In fig 2, we have created a StringBuffer object with the same content. So, in the case of StringBuffer, the length of the content "Hello" is also 5. But is it possible to add some more characters in the existing object or not? Yes, we can add characters in the existing object only because the capacity of StringBuffer is not full. So, here capacity is not 5. Let's understand them with a real-time example.

Real-time Example: 
Assume that there is a classroom. In the classroom, the capacity of classroom is 100. i.e. the total number of students can sit in the classroom is 100. But currently, only 20 students are there. So, many seats are vacant. If the classroom is considered as StringBuffer, length is 20 and capacity is 100. We can add 80 more students in the classroom. That means we can add 80 characters more in the existing object. Hope you will have understood these terminologies clearly in the case of StringBuffer. Now let's move to the main topic StringBuffer constructors

StringBuffer class defines three constructors in Java. They are as follows:
1. StringBuffer(): It creates an empty string buffer with an initial capacity of 16 characters.
2. StringBuffer(int size): It creates an empty string buffer and accepts an integer value that specifies the size or length of the string object.
3. StringBuffer(String str): It creates a string buffer with specified string whose size is equal to the string specified in this constructor.

Creating StringBuffer Class Objects


There are three ways to create a string buffer class objects in Java, and fill the object with a string.
First way: First way for creating a StringBuffer object is that you first allocate the memory for the StringBuffer object by using new operator and later stores the string in it.
    StringBuffer sb=new StringBuffer();
Here, we are creating an empty StringBuffer object with a default initial capacity of 16 characters and not passing any string to it. To store a string in it, we can use append() method like this.
    sb.append("Hello");

Suppose 16 characters are completed. Can we add 17th character in the existing StringBuffer object? Yes, If the StringBuffer object is full, still we can add 17th character in it. Once the capacity of StringBuffer object is filled, a new StringBuffer object will be created with bigger capacity. All the 16th characters will be copied plus 17th character will be added. The reference variable sb will point to new object and the old object by default will be gone to the garbage collector. But these total things will happen internally.

What is the capacity of a new StringBuffer object?
The capacity of a new StringBuffer object can be calculated by using below formula. 
    New capacity=( Current capacity + 1 ) * 2
Thus, New capacity=(16+1)*2=34
Once the 16th character is completed, the next capacity will be 34 if we add 17th character.
Let's see the source code.
Program source code 1:
    package stringBufferPrograms; public class CapacityTest { public static void main(String[] args) { StringBuffer sb=new StringBuffer(); int length=sb.length(); int capacity=sb.capacity(); System.out.println("Before adding any character"); System.out.println("Length=" +length); // length=0 System.out.println("Default initial capacity= " +capacity); // Capacity=16 // Adding 16 characters in the existing object. sb.append("abcdefghijklmnop"); System.out.println("After adding 16 characters"); System.out.println("Length=" +sb.length()); // Now length is 16. System.out.println("Capacity= " +sb.capacity()); // Still capacity is 16. // Now add 17th character in the existing object. sb.append("q"); System.out.println("After adding 17th character"); System.out.println("Length= " +sb.length()); // length is 17. System.out.println("Capacity= " +sb.capacity()); // Capacity is 34. // Add 17 characters in the existing object. sb.append("abcdefghijklmnopq"); // 17 characters. So total=34 characters. // Adding 35th character. sb.append("r"); System.out.println("After adding 35th character"); System.out.println("Length= " +sb.length()); // length is 35. System.out.println("Capacity= " +sb.capacity()); // Capacity is 70. } }
    Output: Before adding any character Length=0 Default initial capacity= 16 After adding 16 characters Length=16 Capacity= 16 After adding 17th character Length= 17 Capacity= 34 After adding 35th character Length= 35 Capacity= 70
As you can see in the above source code, up to the 16th character, still capacity is 16 only. This is because a new StringBuffer object has been created with new capacity when we added 17th character.
When 34 characters are completed and added a 35th character then a new string buffer object with bigger size is again created.
     New capacity=( 34+1 ) * 2 = 70.
Thus, StringBuffer has a growable nature. If the StringBuffer object reaches its maximum capacity, a bigger StringBuffer object is created internally.


Second way: We can create a StringBuffer class object by using the new operator and pass the string to the object.
   StringBuffer sb=new StringBuffer(String s);
For example:
   StringBuffer sb=new StringBuffer("Tech");
    Capacity=sb.length() + 16 = 4+16=20.
Here, we are passing string "Tech" in the StringBuffer object and "sb" is pointing to that object. i.e. the address of the StringBuffer object is stored in reference variable sb.
Program source code 2: 
    package stringBufferPrograms; public class CapacityTest2 { public static void main(String[] args) { StringBuffer sb=new StringBuffer("Tech"); int length=sb.length(); int capacity=sb.length() + 16; System.out.println(length); // 4 System.out.println(capacity); // 20 } }
    Output: 4 20
Third way: We can also create an empty StringBuffer object by declaring a size as an argument for storing characters.
    StringBuffer sb=new StringBuffer(int initialCapacity);
For example:
    StringBuffer sb=new StringBuffer(30);
Here, an empty StringBuffer object has been created with a capacity for storing 30 characters. But it is also possible to store more than 30 characters in this object because StringBuffer is mutable and can expand dynamically in the memory.

What is Mutable String in Java?


A string that can be modified or changed into the existing object is known as mutable string. StringBuffer and StringBuilder classes are used to create a mutable string.
Let's understand the mutable concept with a simple example program and memory concept.

Java StringBuffer Example Programs


Program source code 1: 
    package stringBufferPrograms; public class MutableStringEx { public static void main(String[] args) { StringBuffer sb=new StringBuffer("Scientech"); sb.append(" Easy"); System.out.println(sb); } }
    Output: Scientech Easy
Memory Explanation: Let's understand the memory concept of this program.
StringBuffer class in Java
As you can see that in the above figure no new object is created to add "Easy". It is appended in the existing object because we can perform any required changes in the object when you create a StringBuffer object. This changeable behavior is nothing but mutability. The old object by default will be removed by garbage collector.

Why is String constant pool applicable only for string?


String constant pool is applicable only for string but not for StringBuffer. This is because string is the most common object used in Java whereas StringBuffer is rarely used in the application. Therefore, Java provides special memory management for a string. Without string, you cannot develop any application.

Let's understand one more example program using equals() method and double equal operator in case of StringBuffer.  
Program source code 2: 
    package stringBufferPrograms; public class Test { public static void main(String[] args) { StringBuffer sb1=new StringBuffer("Hello"); // Line 4 StringBuffer sb2=new StringBuffer("Hello"); // Line 5 System.out.println(sb1==sb2); System.out.println(sb1.equals(sb2)); } }
    Output: false false
Memory Explanation: 
StringBuffer class in Java
Whenever we create a string buffer object using the new operator, compulsory a new object will be created in the heap area with content "Hello". Therefore, JVM will create two objects with content "Hello" and the reference variable sb1 and sb2 are pointing to both objects respectively.
Output Explanation: 
1. (sb1==sb2); will return false because both references are pointing to the different objects as shown in the above figure.
2. sb1.equals(sb2); will return false because in the case of StringBuffer, equals() method compare the content based on reference (i.e. address). Both references are pointing to different objects.
Key points: 
1. In case of StringBuffer, equals() method does not override the equals() method of object class. 
2. If you call it using a reference variable, object class equals() method will be called. Object class equals() method compares references, not content as in string.

What is the need for StringBuffer if String is already available?


In this section, we will discuss the need for StringBuffer. There is some situation where we will not recommend to use a string concept. 
1. When content is fixed and it will not change frequently, String class should be used.

2. If the content is not fixed and frequently changing but thread safety is also required, in this situation, we should use for the StringBuffer class.

Let's understand the concept with a suitable example.
Suppose that we have a string "Hello" in string constant pool and it is fixed and not changing frequently, we will need string class. Till now there is no problem. 
Now suppose that if we want to add content "Java" with string "Hello", in this case, compulsory a new object will be created with this change because a string object is immutable. We are not allowed to change in the existing object.

Now suppose the content is changing 10 times internally, 10 times new objects will be created if the string will be used. In this situation, performance will be gone to be down. Memory problem will also create in this situation.
To overcome this kind of requirement, we should go for a StringBuffer. If we will use StringBuffer object and 10 times content is changing then still one object will be created. All the required changes will be performed in the existing object only. But if it is string, for every small change, a new object will be created. Due to which memory will waste and performance will be down. This is the biggest advantage of StringBuffer technique.

Key points: 
1. In the case of String, for every small change, a new object will be created.
2. If StringBuffer is used, for all required changes will perform in the existing object only. No new object will create.

Final words 
Hope that this tutorial has covered almost all the important points related to StringBuffer class in java with suitable example programs. I hope that you will have enjoyed this tutorial.
Thanks for reading!