In Java, String
, StringBuilder
and StringBuffer
are three different classes used for handling text data, but they have distinct characteristics and are used in different scenarios. Although they serve similar purposes, they have distinct characteristics that can significantly impact performance, memory usage, and thread safety. In this article we will explore these differences different scenarios.
Java provides three classes to represent a sequence of characters namely, String
, StringBuilder
and StringBuffer
. Now, it becomes very important for us as developers to know when to use which class.
When to use which class in Java?
String
is immutable whereas StringBuffer and StringBuilder are mutable. Hence, if the content is fixed and wouldn’t change frequently then we should use String. String is more memory-efficient than other two classes if content doesn’t change frequently.StringBuffer
is mutable as well as thread-safe (multiple threads can’t call its methods simultaneously). Hence, if the content is not fixed and would change frequently but thread-safety is also required then we should use StringBuffer. StringBuffer is less efficient than StringBuilder as the former is synchronized.StringBuilder
is mutable but not thread-safe (multiple threads can call its methods simultaneously). Hence, if the content is not fixed and would change frequently but thread-safety is not required then we should use StringBuilder. StringBuilder is more efficient than StringBuffer as the former is non-synchronized.
StringBuffer vs StringBuilder
StringBuffer was the only choice for String manipulation before JDK 5. But, it has one disadvantage that all of its public methods are synchronized. StringBuffer provides Thread safety but at a performance cost. In most of the scenarios, we don’t use String in a multithreaded environment. So Java 1.5 introduced a new class StringBuilder, which is similar to StringBuffer except for thread-safety and synchronization.
String:
- String class represents character strings, we can instantiate String in two ways.
String str = "JAVAOCEAN";
// or
String str = new String("JAVAOCEAN");
- When we create a String using double quotes, JVM first looks for the String in the string pool. If found, it returns the reference of the string object from the String-pool. Otherwise, it creates the String object in the String pool and returns the reference. JVM saves a lot of memory by using the same String in different threads.
String
in Java represents an immutable sequence of characters. Once aString
object is created, its content cannot be changed. Any operation that appears to modify aString
actually creates a newString
object.- It is immutable, meaning its value cannot be changed once created. Every modification leads to a new object. This ensures thread safety but can be inefficient for frequent changes.
- String is immutable in Java. So it’s suitable to use in a multi-threaded environment. We can share it across functions because there is no concern of data inconsistency.
Pros:
- Thread-safe (immutable), making it suitable for use in multi-threaded environments.
- Predictable behavior in terms of memory usage.
Cons:
- Inefficient for frequent string manipulation, as it creates new objects with each modification, leading to performance overhead.
Example:
String str = "Hello";
str = str + " World"; // This creates a new string object
StringBuilder:
StringBuilder
is a mutable alternative to String
. It allows for efficient string manipulation, such as appending, inserting, or modifying characters within the string, without creating new objects.
Pros:
- Mutable, making it suitable for building or modifying strings dynamically.
- Efficient for concatenating or manipulating strings in a loop or when dealing with frequent modifications.
Cons:
- Not thread-safe. If used in a multi-threaded environment, additional synchronization is required (use
StringBuffer
for thread safety).
Example:
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // Efficiently modifies the existing StringBuilder object
StringBuffer:
StringBuffer
is similar toStringBuilder
in terms of mutability and efficient string manipulation. However, it is thread-safe, meaning multiple threads can safely use aStringBuffer
without the risk of data corruption.
Pros:
- Mutable and thread-safe, making it suitable for multi-threaded applications.
- Efficient for concatenating or modifying strings when thread safety is required.
- Cons:
- Slightly less efficient than
StringBuilder
due to thread safety overhead. It’s generally recommended for multi-threaded scenarios.
Example:
StringBuffer buffer = new StringBuffer("Hello");
buffer.append(" World"); // Efficiently modifies the existing StringBuffer object
String vs StringBuffer vs StringBuilder
- String is immutable whereas StringBuffer and StringBuilder are mutable classes.
- StringBuffer is thread-safe and synchronized whereas StringBuilder is not. That’s why StringBuilder is faster than StringBuffer.
- String concatenation operator (+) internally uses StringBuffer or StringBuilder class.
- For String manipulations in a non-multi threaded environment, we should use StringBuilder else use StringBuffer class.
Conclusion
The choice between these classes depends on your specific use case and whether you prioritize mutability, thread safety, or immutability in your application.
- If you need to manipulate strings dynamically and thread safety is not a concern,
StringBuilder
is the preferred choice due to its efficiency. - If you require thread safety, especially in a multi-threaded environment, use
StringBuffer
. - Use
String
when you need an immutable string, and you don’t anticipate frequent modifications.