String, Stringbuffer, and Stringbuilder

Difference between String , StringBuilder & StringBuffer?

I will clarify the thread-safety point. The other points are well described in older questions.

It's quite rare case when StringBuffer suits your needs. While it's thread-safe it doesn't mean you will get what expected when using it from different threads. For example, suppose you have the following code:

StringBuffer buf = new StringBuffer();

public void appendMessage(String message) {
buf.append("INFO: ").append(message).append(System.lineSeparator());
}

If you are using it in multithread environment it will not fail, but you may end up having content like this:

INFO: INFO: thread1 message
thread2 message

That's because individual append calls are synchronized, but the whole sequence is not.

In order to ensure that your messages are separately added, you must have an external synchronization like this:

Object lock = new Object();
StringBuilder buf = new StringBuilder();

public void appendMessage(String message) {
synchronized(lock) {
buf.append("INFO: ").append(message).append(System.lineSeparator());
}
}

Here the whole sequence of calls is synchronized, so you will have the whole message appended at once. And as you are using the external synchronization, StringBuilder will work fine as well.

So in general StringBuffer should not be used in the most of situations.

String, StringBuffer, and StringBuilder

Mutability Difference:

String is immutable, if you try to alter their values, another object gets created, whereas StringBuffer and StringBuilder are mutable so they can change their values.

Thread-Safety Difference:

The difference between StringBuffer and StringBuilder is that StringBuffer is thread-safe. So when the application needs to be run only in a single thread then it is better to use StringBuilder. StringBuilder is more efficient than StringBuffer.

Situations:

  • If your string is not going to change use a String class because a String object is immutable.
  • If your string can change (example: lots of logic and operations in the construction of the string) and will only be accessed from a single thread, using a StringBuilder is good enough.
  • If your string can change, and will be accessed from multiple threads, use a StringBuffer because StringBuffer is synchronous so you have thread-safety.

Difference between StringBuilder and StringBuffer

StringBuffer is synchronized, StringBuilder is not.

Where to use StringBuffer/StringBuilder than String

Below is the main difference between these three most commonly used classes.

  • String class objects are immutable whereas StringBuffer and
    StringBuilder objects are mutable.
  • StringBuffer is synchronized while StringBuilder is not synchronized.
  • Concatenation operator "+" is internal implemented using either
    StringBuffer or StringBuilder.

Criteria to choose among String, StringBuffer and StringBuilder

  • If the Object value is not going to change use String Class because a
    String object is immutable.
  • If the Object value can change and will only be accessed from a
    single thread, use a StringBuilder because StringBuilder is
    unsynchronized.
  • In case the Object value can change, and will be modified by multiple
    threads, use a StringBuffer because StringBuffer is synchronized.

Will the toString() method of StringBuilder or StringBuffer create a new immutable String?

Now if we have a String in a StringBuilder object and we use the toString() method of it, will that create another immutable String in the String pool

You don't have a String in the StringBuilder. The characters are stored in a char[], and when you call toString(), a new String is created:

public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}

That said, creating a new String doesn't add it to the String pool, so there's nothing for you to avoid.

our main purpose of using StringBuilder is to avoid immutable Strings

That's not accurate. The main purpose is to avoid creation of multiple Strings as a result of multiple String concatenations. Using StringBuilder allows you to perform all the concatenations with a single StringBuilder instance. If you want a String representation of the contents of the StringBuilder, you can't avoid creating one String instance. However, you don't have to create a String representation of the StringBuilder contents (unless you need to pass it to a method that requires a String).

Difference between String and StringBuffer in java

Yes, new String objects get created for "try" and "this". The benefit here is that the StringBuffer stores the string of characters internally as a dynamically resized array.

It's more obviously beneficial if we were to concatenate more than two Strings:

"try" + "this" + "test"

This would potentially create 5 String objects because you need intermediate values. (Technically concatenation of literals is performed at compile time so this is just a conceptual example.) It would also be typical for a compiler to refactor the above snippet in to using StringBuilder anyway if they were not literals.

StringBuilder is a newer and non-synchronized version of StringBuffer. In general, you should prefer StringBuilder. The difference between these two classes is covered in "StringBuilder and StringBuffer in Java".

String Buffer to String Builder

There are no errors in replacing StringBuffer sb = new StringBuffer(); to StringBuilder sb = new StringBuilder();

    import java.lang.StringBuilder;

StringBuilder sb = new StringBuilder();
sb.append("Billy ");
sb.append("Scranner");
System.out.println(sb);

sb.insert(5, " D");
System.out.println(sb);
sb.delete(5, 7);

sb.reverse();

System.out.println(sb);

Output:

Billy Scranner
Billy D Scranner
rennarcS ylliB

what is the significance of StringBuffer and which should be used more often, StringBuffer or StringBuilder?

In practice everybody should always use StringBuilder (and never use StringBuffer; often you don't really need StringBuilder because the compiler takes care of adding a helper to do this for you). The only reason StringBuffer is still around is for fear that taking it away would break some code somewhere. Java takes backward compatibility really seriously.

The difference between StringBuffer and StringBuilder is that the methods of StringBuffer are synchronized. That means each thread trying to call a synchronized method has to acquire the lock on the object, this prevents problems where two threads calling methods on the same object could result in the object's state becoming corrupted. The backing data store within the object is a dynamically-growing array, and if two threads are messing with it at the same time and one changes it out from under the other, bad things happen: exceptions get thrown, or worse, data gets stomped on silently.

It turns out that there is not a real life need for a string-building object that concatenates strings received concurrently from multiple threads, because nobody wants a string constructed in a way that makes it unpredictable what order the substrings show up in. It's overwhelmingly likely that when you want to construct a string (and have determined you do need a builder) that builder will be thread-confined (meaning only one thread can access the builder), so no synchronization is needed.

Warning in StringBuffer and StringBuilder

The point is : you are still using the + operator for strings in your expression that you give to append():

... word.substring(0, 1).toUpperCase() + word...

That negates the whole point of using a StringBuilder (or StringBuffer).

Instead: simply call append() twice! The core idea of using a buffer/builder is to concat your desired result by only using append calls; like:

append(word.substring(0, 1).toUpperCase()).append(word...


Related Topics



Leave a reply



Submit