Java中String和StringBuffer有什么区别?
Java中String和StringBuffer有什么区别?
字符串有最大大小吗?
What is the difference between String and StringBuffer in Java?
Is there a maximum size for String?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
String
用于操作不可更改的字符串(只读且不可变)。StringBuffer
用于表示可以修改的字符。从性能角度来看,
StringBuffer
在执行串联时速度更快。这是因为,当您连接String
时,每次都会(在内部)创建一个新对象,因为String
是不可变的。您还可以使用
StringBuilder
,它与StringBuffer
类似,只是它不同步。其中任何一个的最大大小为Integer.MAX_VALUE
(231 - 1 = 2,147,483,647) 或最大堆大小除以 2(请参阅 Java 字符串可以有多少个字符?)。更多信息请参见此处。
String
is used to manipulate character strings that cannot be changed (read-only and immutable).StringBuffer
is used to represent characters that can be modified.Performance wise,
StringBuffer
is faster when performing concatenations. This is because when you concatenate aString
, you are creating a new object (internally) every time sinceString
is immutable.You can also use
StringBuilder
which is similar toStringBuffer
except it is not synchronized. The maximum size for either of these isInteger.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.
String
是不可变的,即当它被创建时,它永远不会改变。当您需要逐段构造字符串而不需要构造大量小
String 的性能开销时,可以使用
StringBuffer
(或其非同步表亲StringBuilder
)一路走来。两者的最大长度都是 Integer.MAX_VALUE,因为它们在内部存储为数组,而 Java 数组只有一个
int
作为其长度伪字段。对于多重串联,
String
和StringBuffer
之间的性能改进非常显着。如果运行以下测试代码,您将看到差异。在我装有 Java 6 的老式笔记本电脑上,我得到以下结果:A
String
is immutable, i.e. when it's created, it can never change.A
StringBuffer
(or its non-synchronized cousinStringBuilder
) is used when you need to construct a string piece by piece without the performance overhead of constructing lots of littleString
s along the way.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.The performance improvement between
String
s andStringBuffer
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 是一个不可变的类。这意味着一旦实例化字符串的实例,如下所示:
内存中的对象无法更改。相反,您必须创建一个新实例,复制旧字符串并附加其他内容,如本例所示:
真正发生的情况是我们没有更新现有的 str1 对象...我们正在重新分配新内存,复制“hello”数据并附加“world!”到最后,然后将 str1 引用设置为指向这个新内存。因此,它实际上看起来更像是这样的:
因此,如果重复执行,尤其是递归执行,这种“复制+粘贴并在内存中移动内容”过程可能会非常昂贵。
当您处于必须一遍又一遍地做事情的情况时,请使用 StringBuilder。它是可变的,并且可以将字符串附加到当前字符串的末尾,因为它由一个[增长数组]返回(如果这是实际的数据结构,则不是 100%,可能是一个列表)。
String is an immutable class. This means that once you instantiate an instance of a string like so:
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:
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:
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).
来自 API:
From the API:
StringBuffer 用于从多个字符串创建单个字符串,例如,当您想要在循环中附加字符串的一部分时。
当只有一个线程访问 StringBuffer 时,您应该使用 StringBuilder 而不是 StringBuffer,因为 StringBuilder 不同步,因此速度更快。
AFAIK 作为一种语言,Java 中的字符串大小没有上限,但 JVM 可能有上限。
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.
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.
AFAIK there is no upper limit for String size in Java as a language, but the JVMs probably have an upper limit.
我找到了 Reggie Hutcherso 比较 String 与 StringBuffer 性能的有趣答案
来源:http:// www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html
Java提供了StringBuffer和String类,String类用于操作不能改变的字符串。简单地说,String 类型的对象是只读且不可变的。 StringBuffer类用于表示可以修改的字符。
这两个类之间的显着性能差异是,在执行简单连接时,StringBuffer 比 String 更快。在字符串操作代码中,字符串通常被连接起来。使用 String 类,连接通常按如下方式执行:
如果要使用 StringBuffer 执行相同的连接,则需要如下所示的代码:
开发人员通常认为上面的第一个示例更有效,因为他们认为第二个示例更有效。使用append方法进行连接的示例比第一个示例(使用+运算符连接两个String对象)成本更高。
+ 运算符看似无辜,但生成的代码却产生了一些惊喜。使用 StringBuffer 进行串联实际上可以生成比使用 String 快得多的代码。为了找出为什么会出现这种情况,我们必须检查两个示例生成的字节码。使用 String 的示例的字节码如下所示:
对于第一行代码,执行位置 0 到 9 的字节码,即:
然后,执行连接的位置 10 到 29 的字节码:
这里事情变得有趣了。为串联生成的字节码创建一个 StringBuffer 对象,然后调用其追加方法:临时 StringBuffer 对象在位置 10 创建,并在位置 23 调用其追加方法。由于 String 类是不可变的,因此必须使用 StringBuffer级联。
对 StringBuffer 对象执行串联后,必须将其转换回 String。这是通过调用位置 26 处的 toString 方法来完成的。该方法从临时 StringBuffer 对象创建一个新的 String 对象。创建这个临时 StringBuffer 对象以及随后将其转换回 String 对象的成本非常高。
总之,上面的两行代码创建了三个对象:
为示例生成的字节码:
现在,让我们看看使用StringBuffer 对于第一行代码,执行位置 0 到 9 的字节码:
然后执行位置 10 到 16 的字节码以进行串联:
请注意,与第一个示例中的情况一样,此代码调用 StringBuffer 的 append 方法目的。然而,与第一个示例不同的是,不需要创建临时 StringBuffer 然后将其转换为 String 对象。此代码仅在位置 0 处创建一个对象,即 StringBuffer。
总之,StringBuffer 串联比 String 串联要快得多。显然,如果可能的话,应该在此类操作中使用 StringBuffer。如果需要 String 类的功能,请考虑使用 StringBuffer 进行串联,然后执行一次到 String 的转换。
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
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.
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:
If you were to use StringBuffer to perform the same concatenation, you would need code that looks like this:
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.
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:
The bytecode at locations 0 through 9 is executed for the first line of code, namely:
Then, the bytecode at location 10 through 29 is executed for the concatenation:
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.
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.
In summary, the two lines of code above result in the creation of three objects:
Now, let's look at the bytecode generated for the example using StringBuffer:
The bytecode at locations 0 to 9 is executed for the first line of code:
The bytecode at location 10 to 16 is then executed for the concatenation:
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.
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.
通过在任何追加操作后打印 String/StringBuffer 对象的哈希码也证明,String 对象每次都会使用新值在内部重新创建,而不是使用相同的 String 对象。
输出:
它打印对象值及其哈希码
By printing the hashcode of the String/StringBuffer object after any append operation also prove, String object is getting recreated internally every time with new values rather than using the same String object.
Output:
It prints object value along with its hashcode
StringBuffer
或其更年轻、更快的兄弟StringBuilder
是首选,每当您要进行大量字符串连接(类似或等效)
时,因为上述构造每次都会隐式创建 new 字符串这将是一个巨大的性能和下降。
StringBuffer
/StringBuilder
的底层最好与可动态扩展的List
进行比较。A
StringBuffer
or its younger and faster brotherStringBuilder
is preferred whenever you're going do to a lot of string concatenations in flavor ofor equivalently
because the above constructs implicitly creates new string everytime which will be a huge performance and drop. A
StringBuffer
/StringBuilder
is under the hoods best to be compared with a dynamically expansibleList<Character>
.String
是一个不可变的字符数组。StringBuffer
是一个可变字符数组。完成变异后通常会转换回String
。由于两者都是数组,因此两者的最大大小都等于整数的最大大小,即 2^31-1(请参见 JavaDoc,另请查看
String
和StringBuffer 的 JavaDoc code>)。这是因为数组的
.length
参数是原始int
。 (请参阅数组)。A
String
is an immutable character array.A
StringBuffer
is a mutable character array. Often converted back toString
when done mutating.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
andStringBuffer
).This is because the.length
argument of an array is a primitiveint
. (See Arrays).字符串是不可变的,这意味着当您对字符串执行操作时,您实际上是在创建一个全新的字符串。
StringBuffer 是可变的,您可以附加到并将其长度重置为 0。
实际上,编译器似乎在字符串连接期间使用 StringBuffer 出于性能原因。
String is immutable, meaning that when you perform an operation on a String you are really creating a whole new String.
StringBuffer is mutable, and you can append to it as well as reset its length to 0.
In practice, the compiler seems to use StringBuffer during String concatenation for performance reasons.
为什么?请查看此处。
进一步的问题,例如何时使用哪些概念和其他概念,可以通过以下方式找出
希望这有帮助。
Why? Check here.
Further questions like when to use which and other concepts can be figured out following this.
Hope this helps.
虽然我知道这不是主要的区别因素,但今天我注意到 StringBuffer(和 StringBuilder)提供了一些 String 没有的有趣方法。
While I understand that this is not a major differentiating factor, I noticed today that StringBuffer(and StringBuilder) provides some interesting methods that String doesn't.
区别在于
String类重写了Object类的toString()、equals()、hashCode(),但StringBuffer仅重写了toString() .
String 类既可序列化 又可比较,但 StringBuffer 只能可序列化< /strong>.
我们可以使用或不使用 new 运算符创建 String 对象,但 StringBuffer 对象只能使用 new 运算符创建。
The differences are
String class is overriding toString(), equals(), hashCode() of Object class, but StringBuffer only overrides toString().
String class is both Serializable as well as Comparable, but StringBuffer is only Serializable.
We can create a String object with and without new operator, but StringBuffer object can only be created using new operator.
性能方面 StringBuffer 比 String 好得多;因为每当您在 String 对象上应用串联时,就会在每个串联上创建新的 String 对象。
主要规则:字符串是不可变的(不可修改)和 StringBuffer 是可变的(可修改)
这是您获得性能差异的编程实验
字符串的输出在我的机器中
14800
StringBuffer 的输出在我的机器中
14
Performance wise StringBuffer is much better than String ; because whenever you apply concatenation on String Object then new String object are created on each concatenation.
Principal Rule : String are immutable(Non Modifiable) and StringBuffer are mutable(Modifiable)
Here is the programmatic experiment where you get the performance difference
Output of String are in my machine
14800
Output of StringBuffer are in my machine
14