Java 中的 String 和 StringBuffer 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2439243/
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
What is the difference between String and StringBuffer in Java?
提问by Praveen
What is the difference between String and StringBuffer in Java?
Java 中的 String 和 StringBuffer 有什么区别?
Is there a maximum size for String?
字符串有最大大小吗?
采纳答案by Vivin Paliath
String
is used to manipulate character strings that cannot be changed (read-only and immutable).
String
用于操作无法更改的字符串(只读和不可变)。
StringBuffer
is used to represent characters that can be modified.
StringBuffer
用于表示可以修改的字符。
Performance wise, StringBuffer
is faster when performing concatenations. This is because when you concatenate a String
, you are creating a new object (internally) every time since String
is immutable.
性能方面,StringBuffer
执行串联时速度更快。这是因为当您连接 a 时String
,您每次都在创建一个新对象(内部),因为它String
是不可变的。
You can also use StringBuilder
which is similar to StringBuffer
except it is not synchronized. The maximum size for either of these is Integer.MAX_VALUE
(231- 1 = 2,147,483,647) or maximum heap size divided by 2 (see How many characters can a Java String have?).
More information here.
您也可以使用StringBuilder
which 类似于StringBuffer
但它不同步。其中任何一个的最大大小是Integer.MAX_VALUE
(2 31- 1 = 2,147,483,647) 或最大堆大小除以 2(请参阅Java 字符串可以有多少个字符?)。更多信息在这里。
回答by Thomas L?tzer
A StringBuffer is used to create a single string from many strings, e.g. when you want to append parts of a String in a loop.
StringBuffer 用于从多个字符串创建单个字符串,例如,当您想在循环中附加字符串的一部分时。
You should use a StringBuilder instead of a StringBuffer when you have only a single Thread accessing the StringBuffer, since the StringBuilder is not synchronized and thus faster.
当您只有一个线程访问 StringBuffer 时,您应该使用 StringBuilder 而不是 StringBuffer,因为 StringBuilder 不同步,因此速度更快。
AFAIK there is no upper limit for String size in Java as a language, but the JVMs probably have an upper limit.
AFAIK 作为一种语言,Java 中的字符串大小没有上限,但 JVM 可能有上限。
回答by Simon Nickerson
A String
is immutable, i.e. when it's created, it can never change.
AString
是不可变的,即当它被创建时,它永远不会改变。
A StringBuffer
(or its non-synchronized cousin StringBuilder
) is used when you need to construct a string piece by piece without the performance overhead of constructing lots of little String
s along the way.
A StringBuffer
(或其非同步表亲StringBuilder
)用于当您需要逐个构建一个字符串而无需在此过程中构建大量小String
s的性能开销。
The maximum length for both is Integer.MAX_VALUE, because they are stored internally as arrays, and Java arrays only have an int
for their length pseudo-field.
两者的最大长度都是 Integer.MAX_VALUE,因为它们在内部存储为数组,而 Java 数组只有int
它们的长度伪字段。
The performance improvement between String
s and StringBuffer
s for multiple concatenation is quite significant. If you run the following test code, you will see the difference. On my ancient laptop with Java 6, I get these results:
String
s 和StringBuffer
s之间对于多重连接的性能提升是相当显着的。如果您运行以下测试代码,您将看到不同之处。在我装有 Java 6 的古老笔记本电脑上,我得到以下结果:
Concat with String took: 1781ms Concat with StringBuffer took: 0ms
public class Concat
{
public static String concatWithString()
{
String t = "Cat";
for (int i=0; i<10000; i++)
{
t = t + "Dog";
}
return t;
}
public static String concatWithStringBuffer()
{
StringBuffer sb = new StringBuffer("Cat");
for (int i=0; i<10000; i++)
{
sb.append("Dog");
}
return sb.toString();
}
public static void main(String[] args)
{
long start = System.currentTimeMillis();
concatWithString();
System.out.println("Concat with String took: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
concatWithStringBuffer();
System.out.println("Concat with StringBuffer took: " + (System.currentTimeMillis() - start) + "ms");
}
}
回答by Pindatjuh
A String
is an immutable character array.
AString
是一个不可变的字符数组。
A StringBuffer
is a mutable character array. Often converted back to String
when done mutating.
AStringBuffer
是可变字符数组。通常String
在完成变异后转换回。
Since both are an array, the maximum size for both is equal to the maximum size of an integer, which is 2^31-1 (see JavaDoc, also check out the JavaDoc for both String
and StringBuffer
).This is because the .length
argument of an array is a primitive int
. (See Arrays).
由于两者都是数组,因此两者的最大大小等于整数的最大大小,即 2^31-1(请参阅JavaDoc,另请查看两者的 JavaDocString
和StringBuffer
)。这是因为.length
数组的参数是一个原始的int
. (参见数组)。
回答by BalusC
A StringBuffer
or its younger and faster brother StringBuilder
is preferred whenever you're going do to a lot of string concatenations in flavor of
每当您要进行大量字符串连接时,首选AStringBuffer
或其更小的和更快的兄弟StringBuilder
string += newString;
or equivalently
或等效地
string = string + newString;
because the above constructs implicitly creates newstring everytime which will be a huge performance and drop. A StringBuffer
/ StringBuilder
is under the hoods best to be compared with a dynamically expansible List<Character>
.
因为上述构造每次都会隐式地创建新字符串,这将带来巨大的性能和下降。A StringBuffer
/StringBuilder
最好与动态可扩展的进行比较List<Character>
。
回答by NguyenDat
I found interest answer for compare performance String vs StringBuffer by Reggie Hutcherso Source: http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html
我找到了 Reggie Hutcherso 比较性能 String 与 StringBuffer 的兴趣答案 来源:http: //www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html
Java provides the StringBuffer and String classes, and the String class is used to manipulate character strings that cannot be changed. Simply stated, objects of type String are read only and immutable. The StringBuffer class is used to represent characters that can be modified.
Java 提供了StringBuffer 和String 类,String 类用于操作不能改变的字符串。简单地说,String 类型的对象是只读且不可变的。StringBuffer 类用于表示可以修改的字符。
The significant performance difference between these two classes is that StringBuffer is faster than String when performing simple concatenations. In String manipulation code, character strings are routinely concatenated. Using the String class, concatenations are typically performed as follows:
这两个类之间的显着性能差异在于,在执行简单串联时,StringBuffer 比 String 更快。在字符串操作代码中,字符串通常是连接在一起的。使用 String 类,连接通常按如下方式执行:
String str = new String ("Stanford ");
str += "Lost!!";
If you were to use StringBuffer to perform the same concatenation, you would need code that looks like this:
如果要使用 StringBuffer 执行相同的串联,则需要如下所示的代码:
StringBuffer str = new StringBuffer ("Stanford ");
str.append("Lost!!");
Developers usually assume that the first example above is more efficient because they think that the second example, which uses the append method for concatenation, is more costly than the first example, which uses the + operator to concatenate two String objects.
开发人员通常认为上面的第一个示例效率更高,因为他们认为使用 append 方法进行连接的第二个示例比使用 + 运算符连接两个 String 对象的第一个示例成本更高。
The + operator appears innocent, but the code generated produces some surprises. Using a StringBuffer for concatenation can in fact produce code that is significantly faster than using a String. To discover why this is the case, we must examine the generated bytecode from our two examples. The bytecode for the example using String looks like this:
+ 运算符看似无害,但生成的代码却出人意料。使用 StringBuffer 进行串联实际上可以生成比使用 String 快得多的代码。要了解为什么会这样,我们必须检查从两个示例中生成的字节码。使用 String 的示例的字节码如下所示:
0 new #7 <Class java.lang.String>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #12 <Method java.lang.String(java.lang.String)>
9 astore_1
10 new #8 <Class java.lang.StringBuffer>
13 dup
14 aload_1
15 invokestatic #23 <Method java.lang.String valueOf(java.lang.Object)>
18 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
21 ldc #1 <String "Lost!!">
23 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
26 invokevirtual #22 <Method java.lang.String toString()>
29 astore_1
The bytecode at locations 0 through 9 is executed for the first line of code, namely:
位置 0 到 9 处的字节码针对第一行代码执行,即:
String str = new String("Stanford ");
Then, the bytecode at location 10 through 29 is executed for the concatenation:
然后,执行位置 10 到 29 处的字节码以进行连接:
str += "Lost!!";
Things get interesting here. The bytecode generated for the concatenation creates a StringBuffer object, then invokes its append method: the temporary StringBuffer object is created at location 10, and its append method is called at location 23. Because the String class is immutable, a StringBuffer must be used for concatenation.
事情在这里变得有趣。为连接生成的字节码创建一个 StringBuffer 对象,然后调用其 append 方法:在位置 10 创建临时 StringBuffer 对象,并在位置 23 处调用其 append 方法。 因为 String 类是不可变的,所以必须使用 StringBuffer级联。
After the concatenation is performed on the StringBuffer object, it must be converted back into a String. This is done with the call to the toString method at location 26. This method creates a new String object from the temporary StringBuffer object. The creation of this temporary StringBuffer object and its subsequent conversion back into a String object are very expensive.
在 StringBuffer 对象上执行连接后,必须将其转换回 String。这是通过调用位置 26 处的 toString 方法完成的。该方法从临时 StringBuffer 对象创建一个新的 String 对象。创建这个临时 StringBuffer 对象并随后将其转换回 String 对象的成本非常高。
In summary, the two lines of code above result in the creation of three objects:
总之,上面的两行代码导致创建了三个对象:
- A String object at location 0
- A StringBuffer object at location 10
- A String object at location 26
- 位置 0 处的 String 对象
- 位置 10 处的 StringBuffer 对象
- 位置 26 处的 String 对象
Now, let's look at the bytecode generated for the example using StringBuffer:
现在,让我们看看使用 StringBuffer 为示例生成的字节码:
0 new #8 <Class java.lang.StringBuffer>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
9 astore_1
10 aload_1
11 ldc #1 <String "Lost!!">
13 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
16 pop
The bytecode at locations 0 to 9 is executed for the first line of code:
第一行代码执行位置 0 到 9 处的字节码:
StringBuffer str = new StringBuffer("Stanford ");
The bytecode at location 10 to 16 is then executed for the concatenation:
然后执行位置 10 到 16 处的字节码以进行连接:
str.append("Lost!!");
Notice that, as is the case in the first example, this code invokes the append method of a StringBuffer object. Unlike the first example, however, there is no need to create a temporary StringBuffer and then convert it into a String object. This code creates only one object, the StringBuffer, at location 0.
请注意,与第一个示例中的情况一样,此代码调用 StringBuffer 对象的 append 方法。然而,与第一个示例不同的是,不需要创建临时 StringBuffer,然后将其转换为 String 对象。此代码仅在位置 0 处创建一个对象 StringBuffer。
In conclusion, StringBuffer concatenation is significantly faster than String concatenation. Obviously, StringBuffers should be used in this type of operation when possible. If the functionality of the String class is desired, consider using a StringBuffer for concatenation and then performing one conversion to String.
总之,StringBuffer 串联明显快于 String 串联。显然,在可能的情况下,应该在此类操作中使用 StringBuffers。如果需要 String 类的功能,请考虑使用 StringBuffer 进行连接,然后执行一次到 String 的转换。
回答by posdef
From the API:
从API:
A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls.
线程安全的、可变的字符序列。字符串缓冲区类似于字符串,但可以修改。在任何时候,它都包含一些特定的字符序列,但可以通过某些方法调用来更改序列的长度和内容。
回答by Matthew Willis
String is immutable, meaning that when you perform an operation on a String you are really creating a whole new String.
String 是不可变的,这意味着当您对 String 执行操作时,您实际上是在创建一个全新的 String。
StringBufferis mutable, and you can append to it as well as reset its length to 0.
StringBuffer是可变的,您可以附加到它并将其长度重置为 0。
In practice, the compiler seems to use StringBuffer during String concatenation for performance reasons.
实际上,出于性能原因,编译器似乎在字符串连接期间使用 StringBuffer 。
回答by Feisty Mango
String is an immutable class. This means that once you instantiate an instance of a string like so:
String 是一个不可变的类。这意味着一旦你像这样实例化一个字符串的实例:
String str1 = "hello";
The object in memory cannot be altered. Instead you will have to create a new instance, copy the old String and append whatever else as in this example:
内存中的对象无法更改。相反,您必须创建一个新实例,复制旧字符串并附加任何其他内容,如本例所示:
String str1 = "hello";
str1 = str1 + " world!";
What is really happening hear is that we are NOT updating the existing str1 object... we are reallocating new memory all together, copying the "hello" data and appending " world!" to the end, then settings the str1 reference to point to this new memory. So it really looks more like this under the hood:
真正发生的事情是我们没有更新现有的 str1 对象......我们正在重新分配新内存,复制“hello”数据并附加“world!” 最后,然后将 str1 引用设置为指向这个新内存。所以它在引擎盖下看起来更像这样:
String str1 = "hello";
String str2 = str1 + " world!";
str1 = str2;
So it follows that this "copy + paste and move stuff around in memory" process can be very expensive if done repitively especially recursively.
因此,如果重复执行,尤其是递归执行,则此“复制 + 粘贴并在内存中移动内容”过程可能会非常昂贵。
When you are in that situation of having to do things over and over utilize StringBuilder. It is mutable and can append strings to the end of the current one because it's back by an [growing array] (not 100% if that is the actual data structure, could be a list).
当您处于必须一遍又一遍地做事情的情况下时,请使用 StringBuilder。它是可变的,并且可以将字符串附加到当前字符串的末尾,因为它后面是一个 [增长数组](如果这是实际的数据结构,则不是 100%,可能是一个列表)。
回答by Karthik Reddy
String StringBuffer
Immutable Mutable
String s=new String("karthik"); StringBuffer sb=new StringBuffer("karthik")
s.concat("reddy"); sb.append("reddy");
System.out.println(s); System.out.println(sb);
O/P:karthik O/P:karthikreddy
--->once we created a String object ---->once we created a StringBuffer object
we can't perform any changes in the existing we can perform any changes in the existing
object.If we are trying to perform any object.It is nothing but mutablity of
changes with those changes a new object of a StrongBuffer object
will be created.It is nothing but Immutability
of a String object
Use String--->If you require immutabilty
Use StringBuffer---->If you require mutable + threadsafety
Use StringBuilder--->If you require mutable + with out threadsafety
String s=new String("karthik");
--->here 2 objects will be created one is heap and the other is in stringconstantpool(scp) and s is always pointing to heap object
String s="karthik";
--->In this case only one object will be created in scp and s is always pointing to that object only