String, StringBuffer, and StringBuilder - Stack Overflowmost recent 30 from stackoverflow.com2026-04-14T08:04:12Zhttps://stackoverflow.com/feeds/question/2971315https://creativecommons.org/licenses/by-sa/4.0/rdfhttps://stackoverflow.com/q/2971315227String, StringBuffer, and StringBuilderJavaUserhttps://stackoverflow.com/users/2971152010-06-04T03:28:55Z2024-05-22T18:22:58Z
<p>What is some real time situation to compare <code>String</code>, <code>StringBuffer</code>, and <code>StringBuilder</code>?</p>
https://stackoverflow.com/questions/2971315/-/2971323#297132311Answer by OscarRyz for String, StringBuffer, and StringBuilderOscarRyzhttps://stackoverflow.com/users/206542010-06-04T03:30:55Z2024-05-22T18:22:58Z<p>You may mean for concatenation.</p>
<p>Real-world example: <em>You want to create a new string out of many others</em>.</p>
<p>For instance, to send a message:</p>
<p><code>String</code> version:</p>
<pre class="lang-java prettyprint-override"><code> String s = "Dear " + user.name + "<br>" +
" I saw your profile and got interested in you.<br>" +
" I'm " + user.age + "yrs. old too"
</code></pre>
<p><code>StringBuilder</code> version:</p>
<pre class="lang-java prettyprint-override"><code> String s = new StringBuilder().append.("Dear ").append(user.name).append("<br>")
.append(" I saw your profile and got interested in you.<br>")
.append(" I'm ").append(user.age).append("yrs. old too")
.toString()
</code></pre>
<p>or</p>
<pre class="lang-java prettyprint-override"><code> String s = new StringBuilder(100).appe..... etc. ...
// The difference is a size of 100 will be allocated
// upfront as fuzzy lollipop points out.
</code></pre>
<p>The <code>StringBuffer</code> version looks like the <code>StringBuilder</code> but the effects differ.</p>
<p>About</p>
<p><code>StringBuffer</code> vs. <code>StringBuilder</code></p>
<p>The former is synchronized and later is not.</p>
<p>So, if you invoke it several times in a single thread (which is 90% of the cases), <code>StringBuilder</code> will run <strong>much</strong> faster, because it won't stop to see if it owns the thread lock.</p>
<p>So, it is recommendable to use <code>StringBuilder</code> (unless of course you have more than one thread accessing to it at the same time, which is rare).</p>
<p><code>String</code> concatenation (<em>using the + operator</em>) may be optimized by the compiler to use <code>StringBuilder</code> underneath, so, it is not longer something to worry about. In the elder days of Java, this was something that everyone says should be avoided at all cost, because every concatenation created a new String object. Modern compilers don't do this anymore, but still it is a good practice to use <code>StringBuilder</code> instead just in case you use an "old" compiler.</p>
<p>Just for those who are curious, this is what the compiler does for this class:</p>
<pre><code>class StringConcatenation {
int x;
String literal = "Value is" + x;
String builder = new StringBuilder().append("Value is").append(x).toString();
}
</code></pre>
<p><code>javap -c StringConcatenation</code></p>
<p>Output:</p>
<pre class="lang-none prettyprint-override"><code>Compiled from "StringConcatenation.java"
class StringConcatenation extends java.lang.Object{
int x;
java.lang.String literal;
java.lang.String builder;
StringConcatenation();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: new #2; //class java/lang/StringBuilder
8: dup
9: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
12: ldc #4; //String Value is
14: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_0
18: getfield #6; //Field x:I
21: invokevirtual #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
24: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
27: putfield #9; //Field literal:Ljava/lang/String;
30: aload_0
31: new #2; //class java/lang/StringBuilder
34: dup
35: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
38: ldc #4; //String Value is
40: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
43: aload_0
44: getfield #6; //Field x:I
47: invokevirtual #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
50: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
53: putfield #10; //Field builder:Ljava/lang/String;
56: return
}
</code></pre>
<p>Lines numbered 5 - 27 are for the String named "literal"</p>
<p>Lines numbered 31-53 are for the String named "builder".</p>
<p>There isn't any difference; exactly the <strong>same</strong> code is executed for both strings.</p>
https://stackoverflow.com/questions/2971315/-/2971331#29713314Answer by Lars Andren for String, StringBuffer, and StringBuilderLars Andrenhttps://stackoverflow.com/users/2953392010-06-04T03:32:42Z2010-06-04T03:32:42Z<p>Also, <code>StringBuffer</code> is thread-safe, which <code>StringBuilder</code> is not.</p>
<p>So in a real-time situation when different threads are accessing it, <code>StringBuilder</code> could have an undeterministic result.</p>
https://stackoverflow.com/questions/2971315/-/2971332#297133249Answer by Artefacto for String, StringBuffer, and StringBuilderArtefactohttps://stackoverflow.com/users/1277242010-06-04T03:33:04Z2011-08-03T14:33:06Z<ul>
<li>You use <a href="http://java.sun.com/javase/6/docs/api/java/lang/String.html" rel="noreferrer"><code>String</code></a> when an immutable structure is appropriate; obtaining a new character sequence from a <code>String</code> may carry an unacceptable performance penalty, either in CPU time or memory (obtaining substrings is CPU efficient because the data is not copied, but this means a potentially much larger amount of data may remain allocated).</li>
<li>You use <a href="http://java.sun.com/javase/6/docs/api/java/lang/StringBuilder.html" rel="noreferrer"><code>StringBuilder</code></a> when you need to create a mutable character sequence, usually to concatenate several character sequences together.</li>
<li>You use <a href="http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html" rel="noreferrer"><code>StringBuffer</code></a> in the same circumstances you would use <code>StringBuilder</code>, but when changes to the underlying string must be synchronized (because several threads are reading/modifyind the string buffer).</li>
</ul>
<p>See an example <a href="http://java.sun.com/docs/books/tutorial/java/data/buffers.html" rel="noreferrer">here</a>.</p>
https://stackoverflow.com/questions/2971315/-/2971343#2971343401Answer by bakkal for String, StringBuffer, and StringBuilderbakkalhttps://stackoverflow.com/users/2386392010-06-04T03:35:13Z2024-04-15T12:12:26Z<p><strong>Mutability Difference:</strong></p>
<p><code>String</code> is <strong>immutable</strong>. If you try to alter their values, another object gets created, whereas <code>StringBuffer</code> and <code>StringBuilder</code> are <strong>mutable</strong>, so they can change their values.</p>
<p><strong>Thread-Safety Difference:</strong></p>
<p>The difference between <code>StringBuffer</code> and <code>StringBuilder</code> is that <code>StringBuffer</code> is threadsafe. So when the application needs to be run only in a single thread, then it is better to use <code>StringBuilder</code>. <code>StringBuilder</code> is more efficient than <code>StringBuffer</code>.</p>
<p><strong>Situations:</strong></p>
<ul>
<li>If your string is not going to change use a String class, because a <code>String</code> object is immutable.</li>
<li>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 <code>StringBuilder</code> is good enough.</li>
<li>If your string can change, and will be accessed from multiple threads, use a <code>StringBuffer</code> because <code>StringBuffer</code> is synchronous so you have thread-safety.</li>
</ul>
https://stackoverflow.com/questions/2971315/-/2971355#297135529Answer by user177800 for String, StringBuffer, and StringBuilderuser177800https://stackoverflow.com/users/02010-06-04T03:37:57Z2024-04-15T12:29:49Z<p><strong>The Basics:</strong></p>
<p><code>String</code> is an immutable class; it can't be changed.
<a href="http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html" rel="nofollow noreferrer"><code>StringBuilder</code></a> is a mutable class that can be appended to, characters replaced or removed and ultimately converted to a <code>String</code>
<code>StringBuffer</code> is the original synchronized version of <code>StringBuilder</code></p>
<p>You should prefer <code>StringBuilder</code> in all cases where you have only a single thread accessing your object.</p>
<p><strong>The Details:</strong></p>
<p>Also note that <code>StringBuilder/Buffers</code> aren't magic. They just use an Array as a backing object and that Array has to be reallocated whenever it gets full. Be sure and create your <code>StringBuilder/Buffer</code> objects large enough originally where they don't have to be constantly resized every time <code>.append()</code> gets called.</p>
<p>The resizing can get very degenerate. It basically resizes the backing Array to two times its current size every time it needs to be expanded. This can result in large amounts of RAM getting allocated and not used when <code>StringBuilder/Buffer</code> classes start to grow large.</p>
<p>In Java, <code>String x = "A" + "B";</code> uses a <code>StringBuilder</code> behind the scenes. So for simple cases there isn't any benefit of declaring your own. But if you are building <code>String</code> objects that are large, say less than 4k, then declaring <code>StringBuilder sb = StringBuilder(4096);</code> is much more efficient than concatenation or using the <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html#StringBuilder--" rel="nofollow noreferrer">default constructor</a> which is only 16 characters. If your <code>String</code> is going to be less than 10k then initialize it with the constructor to 10k to be safe. But if it is initialize to 10k then you write one character more than 10k, it will get reallocated and copied to a 20k array. So initializing high is better than to low.</p>
<p>In the auto resize case, at the 17th character the backing Array gets reallocated and copied to 32 characters, at the 33th character this happens again and you get to reallocated and copy the Array into 64 characters. You can see how this degenerates to <strong>lots</strong> of re-allocations and copies which is what you really are trying to avoid using <code>StringBuilder/Buffer</code> in the first place.</p>
<p>This is from the JDK 6 source code for AbstractStringBuilder:</p>
<pre><code> void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
</code></pre>
<p>A best practice is to initialize the <code>StringBuilder/Buffer</code> a little bit larger than you think you are going to need if you don't know right off hand how big the <code>String</code> will be, but you can guess. One allocation of slightly more memory than you need is going to be better than lots of reallocations and copies.</p>
<p>Also beware of initializing a <code>StringBuilder/Buffer</code> with a <code>String</code> as that will only allocated the size of the String + 16 characters, which in most cases will just start the degenerate reallocation and copy cycle that you are trying to avoid. The following is straight from the Java 6 source code.</p>
<pre><code>public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
</code></pre>
<p>If you by chance do end up with an instance of <code>StringBuilder/Buffer</code> that you didn't create and can't control the constructor that is called, there is a way to avoid the degenerate reallocate and copy behavior. Call <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html#ensureCapacity-int-" rel="nofollow noreferrer"><code>.ensureCapacity()</code></a> with the size you want to ensure your resulting <code>String</code> will fit into.</p>
<p><strong>The Alternatives:</strong></p>
<p>Just as a note, if you are doing really <strong>heavy</strong> <code>String</code> building and manipulation, there is a much more performance-oriented alternative called <a href="http://ahmadsoft.org/ropes/" rel="nofollow noreferrer">Ropes</a>.</p>
<p>Another alternative, is to create a <code>StringList</code> implementation by subclassing <code>ArrayList<String></code>, and adding counters to track the number of characters on every <code>.append()</code> and other mutation operations of the list, then override <code>.toString()</code> to create a <code>StringBuilder</code> of the exact size you need and loop through the list and build the output, you can even make that <code>StringBuilder</code> an instance variable and 'cache' the results of <code>.toString()</code> and only have to regenerate it when something changes.</p>
<p>Also don't forget about <code>String.format()</code> when building fixed formatted output, which can be optimized by the compiler as they make it better.</p>
https://stackoverflow.com/questions/2971315/-/2972441#29724413Answer by Jesper for String, StringBuffer, and StringBuilderJesperhttps://stackoverflow.com/users/1355892010-06-04T08:11:37Z2010-06-04T08:11:37Z<p>Note that if you are using Java 5 or newer, you should use <code>StringBuilder</code> instead of <code>StringBuffer</code>. From the API documentation:</p>
<blockquote>
<p>As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, <code>StringBuilder</code>. The <code>StringBuilder</code> 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.</p>
</blockquote>
<p>In practice, you will almost never use this from multiple threads at the same time, so the synchronization that <code>StringBuffer</code> does is almost always unnecessary overhead.</p>
https://stackoverflow.com/questions/2971315/-/2983748#29837483Answer by fredoverflow for String, StringBuffer, and StringBuilderfredoverflowhttps://stackoverflow.com/users/2520002010-06-06T09:46:37Z2024-04-15T12:31:08Z<p>Personally, I don't think there is any real-world use for <code>StringBuffer</code>. When would I ever want to communicate between multiple threads by manipulating a character sequence? That doesn't sound useful at all, but maybe I have yet to see the light :)</p>
https://stackoverflow.com/questions/2971315/-/24706276#247062762Answer by rajat ghai for String, StringBuffer, and StringBuilderrajat ghaihttps://stackoverflow.com/users/21923032014-07-11T20:45:26Z2024-04-15T11:49:03Z<p>In Java, <strong>String</strong> is immutable. Being immutable we mean that once a String is created, we can not change its value.</p>
<p><strong>StringBuffer</strong> is mutable. Once a StringBuffer object is created, we just append the content to the value of object instead of creating a new object.</p>
<p><strong>StringBuilder</strong> is similar to StringBuffer, but it is not thread-safe. Methods of StingBuilder are not synchronized, but in comparison to other Strings, the Stringbuilder runs the fastest.</p>
<p>You can learn the difference between <a href="https://kb4dev.com/tutorial/java/string,-stringbuffer-and-stringbuilder" rel="nofollow noreferrer">String, StringBuilder and StringBuffer</a> by implementing them.</p>
https://stackoverflow.com/questions/2971315/-/25677937#256779373Answer by Hitesh Garg for String, StringBuffer, and StringBuilderHitesh Garghttps://stackoverflow.com/users/39924202014-09-05T02:45:14Z2024-04-15T13:58:56Z<p>The difference between String and the other two classes is that String is immutable and the other two are mutable classes.</p>
<p><strong>But why do we have two classes for the same purpose?</strong></p>
<p>The reason is that <code>StringBuffer</code> is threadsafe and <code>StringBuilder</code> is not.
<code>StringBuilder</code> is a new class in the StringBuffer` API and it was introduced in <a href="https://en.wikipedia.org/wiki/Java_version_history#Java_5" rel="nofollow noreferrer">JDK 5</a> and is always recommended if you are working in a <a href="https://en.wiktionary.org/wiki/multithreaded#Adjective" rel="nofollow noreferrer">singlethreaded</a> environment as it is much <em>faster</em>.</p>
<p>For complete details, you can read <a href="http://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/" rel="nofollow noreferrer">http://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/</a></p>
https://stackoverflow.com/questions/2971315/-/46428351#464283518Answer by Abhijit Maity for String, StringBuffer, and StringBuilderAbhijit Maityhttps://stackoverflow.com/users/39977432017-09-26T13:50:41Z2024-04-15T12:40:23Z<pre>
-----------------------------------------------------------------
String StringBuffer StringBuilder
-----------------------------------------------------------------
Storage area | Constant string pool Heap Heap
Modifiable | No (immutable) Yes (mutable) Yes (mutable)
Thread Safe | Yes Yes No
Performance | Fast Very slow Fast
-----------------------------------------------------------------
</pre>
https://stackoverflow.com/questions/2971315/-/47454051#474540518Answer by Yash for String, StringBuffer, and StringBuilderYashhttps://stackoverflow.com/users/50818772017-11-23T11:08:13Z2017-11-24T05:59:36Z<p><a href="https://i.sstatic.net/1S4Mz.png" rel="noreferrer"><img src="https://i.sstatic.net/1S4Mz.png" alt="String Family"></a></p>
<p><strong>String</strong></p>
<p>The <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/String.html" rel="noreferrer"><code>String class</code></a> represents character strings. All string literals in Java program, such as <code>"abc"</code> are implemented as instances of this class.</p>
<p>String objects are <strong>immutable</strong> once they are created we can't change. (<em>Strings are constants</em>)</p>
<ul>
<li><p>If a String is created using constructor or method then those strings will be stored in <strong><em>Heap Memory</em></strong> as well as <a href="https://stackoverflow.com/a/37785577/5081877"><strong><em><code>SringConstantPool</code></em></strong></a>. But before saving in pool it invokes <strong><code>intern()</code></strong> method to check object availability with same content in pool using equals method. <em>If String-copy is available in the Pool then returns the reference. Otherwise, String object is added to the pool and returns the reference.</em></p>
<ul>
<li><em>The Java language provides special support for the string concatenation operator (<code>+</code>), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method.</em></li>
</ul>
<p></p>
<pre class="lang-java prettyprint-override"><code>String heapSCP = new String("Yash");
heapSCP.concat(".");
heapSCP = heapSCP + "M";
heapSCP = heapSCP + 777;
// For Example: String Source Code
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
</code></pre>
</li>
<li><p>String literals are stored in <code>StringConstantPool</code>.</p>
<pre class="lang-java prettyprint-override"><code>String onlyPool = "Yash";
</code></pre>
</li>
</ul>
<hr>
<p><strong><a href="https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html" rel="noreferrer">StringBuilder</a> and <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html" rel="noreferrer">StringBuffer</a></strong> are mutable sequence of characters. That means one can change the value of these object's. StringBuffer has the same methods as the StringBuilder, but each method in StringBuffer is synchronized so it is thread safe.</p>
<ul>
<li><p>StringBuffer and StringBuilder data can only be created using new operator. So, they get stored in Heap memory.</p></li>
<li><p><strong><em>Instances of StringBuilder are not safe for use by multiple threads. If such synchronization is required then it is recommended that StringBuffer be used.</em></strong></p>
<pre class="lang-java prettyprint-override"><code>StringBuffer threadSafe = new StringBuffer("Yash");
threadSafe.append(".M");
threadSafe.toString();
StringBuilder nonSync = new StringBuilder("Yash");
nonSync.append(".M");
nonSync.toString();
</code></pre>
</li>
<li><p>StringBuffer and StringBuilder are having a Special methods like.,
<code>replace(int start, int end, String str)</code> and <code>reverse()</code>.</p>
<blockquote>
<p><strong>NOTE</strong>: StringBuffer and SringBuilder are mutable as they provides the implementation of <code>Appendable Interface</code>.</p>
</blockquote></li>
</ul>
<hr>
<p>When to use which one.</p>
<ul>
<li><p>If a you are not going to change the value every time then its better to Use <code>String Class</code>. As part of Generics if you want to Sort <a href="https://stackoverflow.com/a/31244596/5081877"><code>Comparable<T></code></a> or compare a values then go for <code>String Class</code>.</p>
<pre class="lang-java prettyprint-override"><code>//ClassCastException: java.lang.StringBuffer cannot be cast to java.lang.Comparable
Set<StringBuffer> set = new TreeSet<StringBuffer>();
set.add( threadSafe );
System.out.println("Set : "+ set);
</code></pre>
</li>
<li><p>If you are going to modify the value every time the go for StringBuilder which is faster than StringBuffer. If multiple threads are modifying the value the go for StringBuffer.</p></li>
</ul>
https://stackoverflow.com/questions/2971315/-/72996490#729964900Answer by Borislav Stoilov for String, StringBuffer, and StringBuilderBorislav Stoilovhttps://stackoverflow.com/users/56256962022-07-15T15:40:59Z2024-04-15T12:42:27Z<p>Here is a small code snippet illustrating how you can break StringBuilder in an asynchronous environment:</p>
<pre><code>public static void main(String[] args) throws InterruptedException {
StringBuilder builder = new StringBuilder();
ExecutorService executorService = Executors.newFixedThreadPool(50);
for (int i = 0; i < 1000 * 1000; i++) {
executorService.submit(new AppendRunnable(builder));
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES);
Stream.of(builder.toString().split(System.lineSeparator()))
.filter(line -> !line.equals("I just appended this!"))
.forEach(System.out::println);
}
record AppendRunnable(StringBuilder stringBuilder) implements Runnable {
@Override
public void run() {
stringBuilder.append("I just appended this!\n");
}
}
</code></pre>
<p>Essentially, we append strings to the builder and we expect that all of them are equal to "I just appended this!". But they are not; some of them are prefixed with null characters, because the internal character buffer of the builder is not synchronized and it gets wrongly resized. Using StringBuffer in this situation solves the problem. More detailed information is <a href="https://medium.com/@b.stoilov/when-to-use-stringbuffer-in-java-d0a1f57e2477" rel="nofollow noreferrer">here</a>.</p>