Engineering Full Stack Apps with Java and JavaScript
Strings are immutable and a new String object is created every time you modify a String object. When many modifications are done on a String object, it will create as many throw away string objects. In such cases, we can use the mutable StringBuffer and StringBuilder classes instead of the immutable String class.
A StringBuffer is a thread-safe, mutable sequence of characters.
The principal operations on a StringBuffer are the append and insert methods, which are overloaded for most data types and each converts a given data into a string and then appends or inserts.
The append method adds these characters at the end of the buffer.
The insert method adds the characters at a specified point.
Every string buffer has an internal buffer, with an initial capacity. If the internal buffer overflows, it is automatically made larger.
StringBuffer constructors are:
StringBuffer() - Constructs a string buffer with no characters in it and an initial capacity of 16 characters.
StringBuffer(CharSequence seq) - contains the same characters as the specified CharSequence.
StringBuffer(int capacity) - with no characters in it and the specified initial capacity.
StringBuffer(String str) - initialized to the contents of the specified string.
Example: Tricky StringBuffer constructor problem
StringBuffer bf = new StringBuffer('M');
bf will contain nothing.
The statement new StringBuffer('M') returns an empty string buffer with an initial capacity of 77.
The StringBuffer(char) constructor does not exist, but only StringBuffer(int). The compiler selects the int constructor, applying a widening primitive conversion to convert the char value 'M' into the int value 77.
A StringBuilder is similar to StringBuffer, but with no guarantee of thread safety.
Where possible, it is recommended that StringBuilder be used in preference to StringBuffer as it will be faster under most implementations.
StringBuilder was introduced from Java 5 and hence for versions below 5.0, we cannot replace StringBuffer with StringBuilder.
The constructors of StringBuilder are similar to that of StringBuffer. Principal operations on a StringBuilder are the append and insert, same as in StringBuffer.
Since there is no guarantee of synchronization, when the object is being shared between multiple threads, it is safe to use StringBuffer .
Example: StringBuilder vs. String
StringBuilder sb1 = new StringBuilder("123");
String s1 = "123";
sb1.append("abc");
s1.concat("abc");
System.out.println(sb1 + " " + s1);
This prints "123abc 123"
StringBuffer and StringBuilder are mutable and hence if you append data, you will see the changes in the same object.
How can you change the program to print "123abc 123abc"? Change s1.concat("abc"); to s1=s1.concat("abc");
String is immutable and its concat() function append the new data to create a new string and return the new string without modifying the existing one.
So if you need the new string value, you need to assign the newly returned string to the string reference.
If the string is not going to change, use the String class:
As String is immutable it is safe for sharing between multiple threads
If the string is going to change and it will be shared between threads, then use the StringBuffer class:
Allows modification and methods are synchronized,
If the string is to change but will not be shared between the threads (or can have external synchronization), use the StringBuilder class:
Allows modification but does not incur the overhead of synchronization.
Example: Delete and Replace on StringBuffer
Find the output
StringBuffer s = new StringBuffer("123456789");
s.delete(0,3).replace(1,3,"24").delete(4,6);
System.out.println(s);
Output is:
4247
Here, delete() and replace() return a StringBuffer and we are doing chaining of methods.
delete(0,3) gives “456789”
replace(1,3,"24") gives “424789”
delete(4,6) gives “4247”
Example: SubString, Delete and Insert on StringBuffer
Find the output:
StringBuffer s = new StringBuffer("123456789");
s.substring(3,6).delete(1,3).insert(1, "24");
System.out.println(s);
Compilation will fail. Unlike, other StringBuffer methods that return a StringBuffer, substring() returns a String and subsequent operations like delete() which are only applicable for a StringBuffer cannot be applied on a String.
Thread-safe means it can be used safely in a multithreaded environment. You can read and learn more about multithreading in Java @ http://javajee.com/java-multithreading-book.
Comments
Nice article!!!
Nice article!!!