StringBuffer
和StringBuilder
的主要区别是什么?在决定使用其中任何一个时是否存在性能问题?
StringBuffer
和StringBuilder
的主要区别是什么?在决定使用其中任何一个时是否存在性能问题?
StringBuilder
和StringBuffer
几乎相同,唯一的区别是StringBuffer
是同步的,而StringBuilder
不是。虽然StringBuilder
比StringBuffer
更快,但性能差异非常小。 StringBuilder
是SUN公司替代StringBuffer
的产品,它在所有公共方法中避免了同步。除此之外,它们的功能是相同的。
良好使用示例:
如果您的文本将要更改并被多个线程使用,则最好使用StringBuffer
。如果您的文本将要更改,但仅由单个线程使用,请使用StringBuilder
。
String
是不可变的。
StringBuffer
是可变的且同步的。
StringBuilder
也是可变的但它不是同步的。
javadoc解释了它们之间的区别:
该类提供与StringBuffer兼容的API,但不能保证同步。该类旨在用作StringBuffer的替代品,在只有一个线程使用字符串缓冲区的情况下(通常是这种情况),可以将其放置在原来StringBuffer的位置。如果可能的话,建议优先使用该类而不是StringBuffer,因为在大多数实现下它将更快。
StringBuilder
(在Java 5中引入)与StringBuffer
完全相同,除了其方法未同步。这意味着它比后者更具性能优势,但缺点是它不是线程安全的。
阅读教程以获取更多详细信息。
/**
* Run this program a couple of times. We see that the StringBuilder does not
* give us reliable results because its methods are not thread-safe as compared
* to StringBuffer.
*
* For example, the single append in StringBuffer is thread-safe, i.e.
* only one thread can call append() at any time and would finish writing
* back to memory one at a time. In contrast, the append() in the StringBuilder
* class can be called concurrently by many threads, so the final size of the
* StringBuilder is sometimes less than expected.
*
*/
public class StringBufferVSStringBuilder {
public static void main(String[] args) throws InterruptedException {
int n = 10;
//*************************String Builder Test*******************************//
StringBuilder sb = new StringBuilder();
StringBuilderTest[] builderThreads = new StringBuilderTest[n];
for (int i = 0; i < n; i++) {
builderThreads[i] = new StringBuilderTest(sb);
}
for (int i = 0; i < n; i++) {
builderThreads[i].start();
}
for (int i = 0; i < n; i++) {
builderThreads[i].join();
}
System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());
//*************************String Buffer Test*******************************//
StringBuffer sb2 = new StringBuffer();
StringBufferTest[] bufferThreads = new StringBufferTest[n];
for (int i = 0; i < n; i++) {
bufferThreads[i] = new StringBufferTest(sb2);
}
for (int i = 0; i < n; i++) {
bufferThreads[i].start();
}
for (int i = 0; i < n; i++) {
bufferThreads[i].join();
}
System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());
}
}
// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {
StringBuilder sb;
public StringBuilderTest (StringBuilder sb) {
this.sb = sb;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
sb.append("A");
}
}
}
//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {
StringBuffer sb2;
public StringBufferTest (StringBuffer sb2) {
this.sb2 = sb2;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
sb2.append("A");
}
}
}
建议使用StringBuilder
,因为它不会进行同步操作,因此性能更好。 StringBuilder
是旧的StringBuffer
的替代品。
StringBu(ff|ild)er
都是局部变量,只被单个线程使用。 - gabuzo字符串构建器:
int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.
字符串缓冲区
StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);
建议在可能的情况下使用StringBuilder,因为它比StringBuffer更快。但是,如果需要线程安全,则最好选择StringBuffer对象。
StringBuffer:
StringBuilder:
String c = a + b
等同于 String c = new StringBuilder().append(a).append(b).toString()
,所以它并不更快。只是每次字符串赋值时都会创建一个新的字符串对象,而你本可以只有一个 (String d = a + b; d = d + c;
等同于 String d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString();
而 StringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString();
可以节省一个 StringBuilder 实例化)。 - Chop