1. Introduction
When working with text in Java, programmers have three options: String, StringBuilder and StringBuffer. Each class has its special features that make them useful in different situations. Understanding when to use each one is crucial for writing efficient code.
In this article, we shall explore the differences between those three classes and guide on using each while considering individual application requirements.
2. StringBuilder class
StringBuilder class in Java is used to add characters to a sequence. Those characters can be modified after the initial creation because the StringBuilder object is mutable. StringBuilder nature is similar to StringBuffer, but it is not thread-safe and, as a result, faster than StringBuffer, but it should not be used in a multi-threaded environment.
StringBuilder class is useful when you need to append multiple strings together. Creating a new string every time you concatenate two strings together is inefficient. The StringBuilder object allows you to append text to an existing String without creating a new one every single time.
Below is an example of how to create a StringBuilder class, append it, and convert it back to a String object.
public static String createUsingStringBuilder() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("Hello "); stringBuilder.append("World"); return stringBuilder.toString(); }
3. StringBuffer class
StringBuffer is a mutable class which can hold a sequence of characters. It is similar to the String class, but unlike String, StringBuffer is mutable, which means that the contents of a StringBuffer object can be modified after initial creation. This makes StringBuffer a more flexible class than String when the text value needs to be modified during the program execution.
StringBuffer is thread-safe so that it can be safely used in a multi-threaded environment. The StringBuffer object synchronization mechanism allows one thread access at a time. However, this comes at a certain cost, affecting the performance of your code.
StringBuffer class is typically used when you modify a String multiple times, e.q. when building a long String object from small parts of characters. Due to StringBuffer’s mutable nature, you can append, insert, or delete characters from a StringBuffer object without creating a new object each time. In this circumstance, this is more efficient than using the String class, which requires a new object to be created each time a modification is made.
Here is an example of a StringBuffer class in Java.
public static String createUsingStringBuffer() { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("Hello "); stringBuffer.append("World"); return stringBuffer.toString(); }
4. String
The String is a fundamental class in Java that represents a sequence of characters. It is immutable, so its value cannot be changed once a String is created. Any operation that appears to modify a String creates a new String object using the modified value. This is quite memory inefficient, especially when concatenating multiple Strings together.
The String is a good choice when you need to represent a constant text value that will not change during the program’s execution. For example, if you need to store a message that will be displayed to the user, you can use a String.
Strings are good candidates to be used in a multi-threaded environment. When you create a String object that already exists, JVM efficiently will return an existing reference from the String pool. This saves application memory since no multiple Strings with the same value can exist.
Below is an example of two String objects, one using a string literal and the other using the String constructor:
public static void creteString() { String text = "Hello"; String textTwo = new String("world"); }
To summarize, here are some of the advantages and disadvantages of using String:
- Advantages:
- Easy to use and understand
- Immutable and thread-safe
- Memory efficient for constant Strings
- Disadvantages:
- Not efficient for concatenating multiple Strings
- Creates a new object every time a String is modified
5. Comparison between String, StringBuffer and StringBuilder
Since you already know that Java has three different classes for text manipulation. Next, look at each and compare their features while highlighting their obvious differences.
Immutability
The String class is immutable and cannot be modified once an object is created. However, StringBuilder and StringBuffer are mutable, and the object’s contents can be modified.
Thread Safety
StringBuffer is designed to be used in a multi-threaded environment and will therefore protect shared data from thread interference. On the other hand, if you are working with single threads of execution, it would be best to utilize StringBuilder, as this class is not inherently thread-safe.
Performance
StringBuilder reigns superior to StringBuffer when it comes to speed since it does not need the overhead of synchronization. Yet, if your program necessitates thread safety, you should use StringBuffer instead.
Memory Usage
String objects are stored in the string pool, which can lead to memory wastage if many String objects are created. On the other hand, StringBuilder and StringBuffer allocate memory dynamically and can be used to reduce memory wastage.
Usage
A String should be used when the contents of the String are not going to change. StringBuilder should be used when the string’s contents change frequently in a single-threaded environment. StringBuffer should be used when the contents of the String change frequently in a multi-threaded environment.
6. StringBuilder and StringBuffer Performance
If you are looking for speed in concatenating Strings, StringBuilder and StringBuffer have the advantage over String object. It is important, however, to note that there are minor distinctions between the two of them.
StringBuffer is synchronized, which means it is thread-safe. This makes it a good choice for multi-threaded environments, where multiple threads might access and modify the same string. However, this synchronization comes at a cost, and StringBuffer can be slower than StringBuilder in single-threaded environments.
By contrast, StringBuilder does not need to be synchronized and therefore is faster in single-threaded environments than its counterpart StringBuffer. Moreover, because there is no requirement for synchronization, using a StringBuilder will result in less memory consumption when compared with using a StringBuffer.
Nevertheless, StringBuilder is not a safe option in multi-threaded settings and can cause race conditions or other synchronisation-related issues. It’s imperative to select the right class for your particular requirement accordingly.
Based on what we have explored, we will prove the performance difference between StringBuilder and StringBuffer. Both methods are very similar, but StringBuffer methods are synchronized, and StringBuilder are not. Doesn’t seem like much but makes a massive difference.
Let’s look at the following example of performance differences between StringBuilder and StringBuffer.
public static void stringBufferPerformance() { long startTime = System.currentTimeMillis(); StringBuffer stringBuffer = new StringBuffer(); IntStream.range(0, 100000) .forEach(num -> stringBuffer.append("testText")); long elapsed = (System.currentTimeMillis() - startTime); System.out.println("Elapsed by StringBuffer: " + elapsed + "ms"); }
public static void stringBuilderPerformance() { long startTime = System.currentTimeMillis(); StringBuilder stringBuilder = new StringBuilder(); IntStream.range(0, 100000) .forEach(num -> stringBuilder.append("testText")); long elapsed = (System.currentTimeMillis() - startTime); System.out.println("Elapsed by StringBuilder: " + elapsed + "ms"); }
Elapsed by StringBuffer: 9ms Elapsed by StringBuilder: 4ms
Executing two similar methods in both classes. The results vary with each run, but what is clear is that StringBuilder is at least twice faster than a StringBuffer.
7. Summary
This article has looked at when to use StringBuilder, StringBuffer and String in Java. When considering Java’s trio of text players, the immutable String class is ideal for when your sequence stays put. However, if you want to get things moving a little faster – and in single-threaded environments – opt for StringBuilder instead of its synchronized sibling, StringBuffer.
Daniel Barczak
Daniel Barczak is a software developer with a solid 9-year track record in the industry. Outside the office, Daniel is passionate about home automation. He dedicates his free time to tinkering with the latest smart home technologies and engaging in DIY projects that enhance and automate the functionality of living spaces, reflecting his enthusiasm and passion for smart home solutions.
Leave a Reply