2

I have read in a Java book that says:

Because a String is immutable, using StringBuffer is more efficient.

I understand that String instances are immutable.

I also understand that StringBuffer makes processing Strings more effcient than normal.

But the thing I can't work out is what connects these two concepts, i.e. how does String being immutable help StringBuffer?

Thanks :)

3
  • 2
    Being immutable makes String slower. Thus, StringBuffer becomes a better alternative. There should be no direct linkage between the two. Commented Mar 28, 2012 at 3:25
  • From the Javadoc for StringBuffer in Java 5.0 from 2004 As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, StringBuilder. The StringBuilder class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization. If you are concerned about performance, don't use StringBuffer. Commented Mar 28, 2012 at 7:13
  • 1
    @AmitBhargava - Immutable Strings are slower for some things, but faster for others. For instance, substring (with usable semantics) is typically faster than if String was mutable, because it is not necessary to copy the characters. But I'd agree that overall, immutability makes Strings slower (probably). Commented Apr 5, 2012 at 4:22

5 Answers 5

8

Because Strings are immutable, to manipulate Strings, such as to concatenate Strings, you have to create new String objects, since obviously, you can't change the state of existing String objects. Whereas with a StringBuffer or StringBuilder, you create one object and simply change its state. If you're doing some major String concatenation in a for loop for instance, this object creation can get very expensive.

That being said, I see many posts here critical of simple String concatenation that don't involve large-scale concatenation, and in that situation using a StringBuffer or StringBuilder is an example of premature and unnecessary optimization.

Also note that you should use StringBuilder preferentially over StringBuffer unless your application needs to access the object in multiple threads and doesn't mind the extra overhead that this incurs.

Sign up to request clarification or add additional context in comments.

5 Comments

Oh. It means: if I want to concatenate String "abc" and "def" but not using Buffer. In String pool will have: "abc" "abcd" "abcde" "abcdef". But if use buffer, just have "abc", "abcdef", "def". Right ?
Incorrect. First off, your example is trivial and would suggest that simply using Strings is the best way to go. The pool would have "abc", "def" and "abcdef" for simply using Strings.
@hqt - no, there will just be abc, def, and abcdef. But imagine concatenating 10 or more strings together in a loop - then you'd get a new string for each concatenation. On the other hand, the compiler will optimize where it can. For instance, literal "abc" + "def" is concatenated at compile-time, not runtime. And if you do multiple runtime concatenations in a single statement, it will make one StringBuilder and do appends - just as you would write by hand using StringBuilder yourself. See stackoverflow.com/questions/1532461.
+1 for pointing out that using StringBuilder is more efficient (since efficiency was the point of not using Strings) than StringBuffer when not having to worry about concurrency.
It should be noted that the reason that the hand optimization (Hovercraft's 2nd paragraph) is unnecessary is that the Java compiler can and will do effectively the same optimization itself ...
2

What it meant to say to is that since String is immutable therefore it is better to use StringBuffer (or StringBuilder) for String manipulation since you're not creating new object every time you change underlying String.

1 Comment

Oh. It means: if I want to concatenate String "abc" and "def" but not using Buffer. In String pool will have: "abc" "abcd" "abcde" "abcdef". But if use buffer, just have "abc", "abcdef", "def". Right ?
1

But the thing I can't work out is what connects these two concepts, i.e. how does String being immutable help StringBuffer?

It doesn't. I think that you are simply misinterpreting the sentence that you quoted.

"Because a String is immutable, using StringBuffer is more efficient."

It is saying that StringBuffer is a relative more efficient option (for certain tasks). In other words: "Because a String is immutable, using StringBuffer is more efficient [than using String for certain tasks].".

It is NOT saying that StringBuffer is faster in absolute terms than it would be if String wasn't immutable. Certainly, that's not how I read the quote ... and it is not a true statement either.

Comments

1

All the other posts definitely answer the question. I would add that you should always choose StringBuilder over StringBuffer. StringBuffer has built-in thread synchronization, which is a whole lot of locking overhead that you will almost never need. StringBuilder does not have this, and is therefore faster.

In fact, even if you want thread safety, here are some very good reasons not to use StringBuffer.

Comments

0

The concept of immutable can easily be explained with this example

String s1 = "Hello";
String s2 = "Hi";
String s3 = "Hello";

if (s1 == s2){ System.out.println("s1==s2");}
if (s1 == s3){ System.out.println("s1==s3");}

s1 = "Hi";

if (s1 == s2){ System.out.println("s1==s2");}
if (s1 == s3){ System.out.println("s1==s3");}

If you execute this piece of code you would get s1==s3 and s1==s2. What does this example explains?

When you created s1, the compiler created a string "Hello" in its string table (i dun remember its exact name). When you created s2, it create new object "Hi". Now when you created s3, compiler knows that there is an object "Hello" already in its string table, so why not just refer s3 to it. So s1=s3 (memory vise). Same happened when you assigned value "hi" to s1, compiler could see that "hi" is already in the memory being pointed by s3, so it pointed it to s1 as well.

In case of StringBuffer, Compiler allocates memory to the object, which you can manipulate rather "pool" as in case of String.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.