为什么在 Java 中使用 StringBuffer 而不是字符串连接运算符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/65668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why to use StringBuffer in Java instead of the string concatenation operator
提问by
Someone told me it's more efficient to use StringBuffer
to concatenate strings in Java than to use the +
operator for String
s. What happens under the hood when you do that? What does StringBuffer
do differently?
有人告诉我,StringBuffer
在 Java 中使用连接字符串比使用s的+
运算符更有效String
。当你这样做时,引擎盖下会发生什么?有什么StringBuffer
不同?
回答by André Chalella
One shouldn't be faster than the other. This wasn't true before Java 1.4.2, because when concatenating more than two strings using the "+" operator, intermediate String
objects would be created during the process of building the final string.
一个不应该比另一个快。在 Java 1.4.2 之前,情况并非如此,因为当使用“+”运算符连接两个以上的字符串时,String
会在构建最终字符串的过程中创建中间对象。
However, as the JavaDoc for StringBufferstates, at least since Java 1.4.2 using the "+" operator compiles down to creating a StringBuffer
and append()
ing the many strings to it. So no difference, apparently.
但是,正如StringBuffer的JavaDoc所述,至少从 Java 1.4.2 开始使用“+”运算符编译为创建 aStringBuffer
并将append()
许多字符串添加到它。所以没有区别,显然。
However, be careful when using adding a string to another inside a loop! For example:
但是,在循环中将字符串添加到另一个字符串时要小心!例如:
String myString = "";
for (String s : listOfStrings) {
// Be careful! You're creating one intermediate String object
// for every iteration on the list (this is costly!)
myString += s;
}
Keep in mind, however, that usually concatenating a few strings with "+" is cleaner than append()
ing them all.
但是请记住,通常用“+”连接几个字符串比将append()
它们全部连接起来更干净。
回答by jodonnell
Under the hood, it actually creates and appends to a StringBuffer, calling toString() on the result. So it actually doesn't matter which you use anymore.
在幕后,它实际上创建并附加到 StringBuffer,对结果调用 toString()。所以实际上你使用哪个并不重要。
So
所以
String s = "a" + "b" + "c";
becomes
变成
String s = new StringBuffer().append("a").append("b").append("c").toString();
That's true for a bunch of inlined appends within a single statement. If you build your string over the course of multiple statements, then you're wasting memory and a StringBuffer or StringBuilder is your better choice.
对于单个语句中的一堆内联附加,这是正确的。如果您在多个语句的过程中构建字符串,那么您就是在浪费内存,而 StringBuffer 或 StringBuilder 是您更好的选择。
回答by Ivan Bosnic
Because Strings are imutable in Java, every time you concanate a String, new object is created in memory. SpringBuffer use the same object in memory.
因为字符串在 Java 中是不可变的,所以每次连接字符串时,都会在内存中创建新对象。SpringBuffer 在内存中使用相同的对象。
回答by Loren Segal
StringBuffer is mutable. It adds the value of the string to the sameobject without instantiating another object. Doing something like:
StringBuffer 是可变的。它将字符串的值添加到同一个对象而不实例化另一个对象。做类似的事情:
myString = myString + "XYZ"
will create a newString object.
将创建一个新的String 对象。
回答by Alan Krueger
Java turns string1 + string2 into a StringBuffer construct, append(), and toString(). This makes sense.
Java 将 string1 + string2 转换为 StringBuffer 构造、append() 和 toString()。这是有道理的。
However, in Java 1.4 and earlier, it would do this for each+ operator in the statement separately. This meant that doing a + b + c would result in twoStringBuffer constructs with twotoString() calls. If you had a long string of concats, it would turn into a real mess. Doing it yourself meant you could control this and do it properly.
然而,在Java 1.4和更早的版本,它会做到这一点的每个在声明+运营商分开。这意味着执行 a + b + c 将导致两个StringBuffer 构造和两个toString() 调用。如果你有一长串 concats,它会变成一团糟。自己做意味着你可以控制它并正确地做到这一点。
Java 5.0 and above seem to do it more sensibly, so it's less of a problem and is certainly less verbose.
Java 5.0 及更高版本似乎更明智地做到了这一点,因此问题不大,当然也不那么冗长。
回答by Eclipse
To concatenate two strings using '+', a new string needs to be allocated with space for both strings, and then the data copied over from both strings. A StringBuffer is optimized for concatenating, and allocates more space than needed initially. When you concatenate a new string, in most cases, the characters can simply be copied to the end of the existing string buffer.
For concatenating two strings, the '+' operator will probably have less overhead, but as you concatenate more strings, the StringBuffer will come out ahead, using fewer memory allocations, and less copying of data.
要使用“+”连接两个字符串,需要为两个字符串分配一个新字符串,然后从两个字符串复制数据。StringBuffer 针对连接进行了优化,并分配了比最初所需更多的空间。当您连接一个新字符串时,在大多数情况下,可以简单地将字符复制到现有字符串缓冲区的末尾。
对于连接两个字符串,'+' 运算符的开销可能会更少,但是当您连接更多的字符串时,StringBuffer 会提前出现,使用更少的内存分配和更少的数据复制。
回答by Calum
It's better to use StringBuilder (it's an unsynchronized version; when do you build strings in parallel?) these days, in almost every case, but here's what happens:
现在,几乎在所有情况下,最好使用 StringBuilder(它是一个非同步版本;你什么时候并行构建字符串?),但这里是发生了什么:
When you use + with two strings, it compiles code like this:
当您对两个字符串使用 + 时,它会编译如下代码:
String third = first + second;
To something like this:
对于这样的事情:
StringBuilder builder = new StringBuilder( first );
builder.append( second );
third = builder.toString();
Therefore for just little examples, it usually doesn't make a difference. But when you're building a complex string, you've often got a lot more to deal with than this; for example, you might be using many different appending statements, or a loop like this:
因此,对于一些小例子,它通常没有什么区别。但是当你构建一个复杂的字符串时,你通常需要处理的远不止这些;例如,您可能会使用许多不同的附加语句,或者像这样的循环:
for( String str : strings ) {
out += str;
}
In this case, a new StringBuilder
instance, and a new String
(the new value of out
- String
s are immutable) is required in each iteration. This is very wasteful. Replacing this with a single StringBuilder
means you can just produce a single String
and not fill up the heap with String
s you don't care about.
在这种情况下,一个新的StringBuilder
实例,以及一个新的String
(新值out
- String
s为不可变的)需要在每一次迭代。这是非常浪费的。用单个替换它StringBuilder
意味着你可以只生成一个,String
而不用String
你不关心的 s填充堆。
回答by Calum
The StringBuffer class maintains an array of characters to hold the contents of the strings you concatenate, whereas the + method creates a new string each time its called and appends the two parameters (param1 + param2).
StringBuffer 类维护一个字符数组来保存您连接的字符串的内容,而 + 方法每次调用时都会创建一个新字符串并附加两个参数 (param1 + param2)。
The StringBuffer is faster because 1. it might be able to use its already existing array to concat/store all of the strings. 2. even if they don't fit in the array, its faster to allocate a larger backing array then to generate new String objects for each evocation.
StringBuffer 更快,因为 1. 它可能能够使用其已经存在的数组来连接/存储所有字符串。2. 即使它们不适合数组,分配更大的支持数组然后为每次调用生成新的 String 对象会更快。
回答by slipset
I think that given jdk1.5 (or greater) and your concatenation is thread-safe you should use StringBuilder instead of StringBuffer http://java4ever.blogspot.com/2007/03/string-vs-stringbuffer-vs-stringbuilder.htmlAs for the gains in speed: http://www.about280.com/stringtest.html
我认为鉴于 jdk1.5(或更高版本)并且您的连接是线程安全的,您应该使用 StringBuilder 而不是 StringBuffer http://java4ever.blogspot.com/2007/03/string-vs-stringbuffer-vs-stringbuilder.html至于速度上的提升:http: //www.about280.com/stringtest.html
Personally I'd code for readability, so unless you find that string concatenation makes your code considerably slower, stay with whichever method makes your code more readable.
就我个人而言,我会编码以提高可读性,因此除非您发现字符串连接使您的代码变慢,否则请继续使用使您的代码更具可读性的任何方法。
回答by Adam Rosenfield
Because Strings are immutable, each call to the + operator creates a new String object and copies the String data over to the new String. Since copying a String takes time linear in the length of the String, a sequence of N calls to the + operator results in O(N2) running time (quadratic).
因为字符串是不可变的,所以每次调用 + 运算符都会创建一个新的 String 对象并将 String 数据复制到新的 String 中。由于复制 String 花费的时间与 String 的长度成线性,因此对 + 运算符的 N 次调用导致 O(N 2) 运行时间(二次)。
Conversely, since a StringBuffer is mutable, it does not need to copy the String every time you perform an Append(), so a sequence of N Append() calls takes O(N) time (linear). This only makes a significant difference in runtime if you are appending a large number of Strings together.
相反,由于 StringBuffer 是可变的,它不需要在每次执行 Append() 时复制 String,因此 N Append() 调用的序列需要 O(N) 时间(线性)。如果您将大量字符串附加在一起,这只会在运行时产生显着差异。