String,StringBuffer和StringBuilder的区别

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

【java面试题】StringBuilder与StringBuffer和String 的区别

很多人对String和StringBuffer的区别已经很了解了吧,可能还有人对这两个类的工作原理有些不清楚的地方,复习一下吧,顺便牵出J2SE 5.0里面带来的一个新的字符操作的类StringBuilder。那么这个StringBuilder和StringBuffer 以及我们最早遇见的String 类有那些区别呢?在不同的场合下我们应该用哪个呢?我讲讲自己对这几个类的一点看法,也希望大家提出意见。

简要的说,String类型和StringBuffer类型的主要性能区别其实在于String 是不可变的对象,因此在每次对String类型进行改变的时候其实都等同于生成了一个新的String对象,然后将指针指向新的String对象,所以经常改变内容的字符串最好不要用String,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM 的GC就会开始工作,那速度是一定会相当慢的。这里尝试举个不是很恰当的例子:

String Str = “abc”;

For(int i = 0 ; i < 10000 ; i++)

{

Str + = “def”;

}

如果是这样的话,到这个for 循环完毕后,如果内存中的对象没有被GC 清理掉的话,内存中一共有上万个了,惊人的数目,而如果这是一个很多人使用的系统,这样的数目就不算很多了,所以大家使用的时候一定要小心。

而如果是使用StringBuffer类则结果就不一样了,每次结果都会对StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用StringBuffer,特别是字符串对象经常改变的情况下。而在某些特别情况下,String 对象的字符串拼接其实是被JVM 解释成了StringBuffer 对象的拼接,所以这些时候String 对象的速度并不会比StringBuffer 对象慢,而特别是以下的字符串对象生成中,String 效率是远要比StringBuffer 快的:

String Str = “This is only a” + “ simple” + “ test”;

StringBuffer Sb = new StringBuil der(“This is only a”).append(“ simple”).append(“ test”);

你会很惊讶的发现,生成String Str 对象的速度简直太快了,而这个时候StringBuffer 居然速度上根本一点都不占优势。其实这是JVM 的一个把戏,在JVM 眼里,这个

String Str = “This is only a” + “ simple” + “test”; 其实就是:

String Str = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String 对象的话,速度就没那么快了,譬如:

String S2 = “This is only a”;

String S3 = “ simple”;

String S4 = “ test”;

String S1 = S2 +S3 + S4;

这时候JVM 会规规矩矩的按照原来的方式去做,S1 对象的生成速度就不像刚才那么快了,一会儿我们可以来个测试作个验证。

由此我们得到第一步结论:

在大部分情况下StringBuffer > String

而StringBuilder 跟他们比又怎么样呢?先简单介绍一下,StringBuilder 是JDK5.0 中新增加的一个类,它跟StringBuffer 的区别看下面的介绍:

ng.StringBuffer线程安全的可变字符序列。类似于String 的字符串缓冲区,但不能修改。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。

每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从JDK 5.0 开始,为该类增添了一个单个线程使用的等价类,即StringBuilder 。与该类相比,通常应该优先使用StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。

但是如果将StringBuilder 的实例用于多个线程是不安全的。需要这样的同步,则建议使用StringBuffer 。

那么下面我们再做一个一般性推导:

在大部分情况下StringBuilder > StringBuffer

因此,根据这个不等式的传递定理:在大部分情况下

StringBuilder > StringBuffer > String

====================================================================

String是一个类,但却是不可变的,所以String创建的算是一个字符串常量,StringBuffer和StringBuilder 都是可变的。所以每次修改String对象的值都是新建一个对象再指向这个对象。而使用StringBuffer则是对StringBuffer对象本身进行操作。所以在字符串j经常改变的情况下,使用StringBuffer要快得多。

但在某些情况下:

Java代码

1. String S1 = “Who” + “ is” + “ faster?”;

2. StringBuffer Stb = new StringBuilder(“Who”).append(“ is”).append(“ faster?”);

Java代码

1. String S1 = “Who” + “ is” + “ faster?”;

2. StringBuffer Stb = new StringBuilder(“Who”).append(“ is”).append(“ faster?”);

S1的素对会比Stb快得多,是因为JVM把String对象的拼接解释成了StringBuffer对象的拼接,其实在JVM就是:

Java代码

1. String S1="Who is faster?";

Java代码

1. String S1="Who is faster?";

不过如果,字符串是来自其他对象,如:

Java代码

1. String s1="Who";

2. String s2=" is";

3. String s3=" faster?";

4. String st=s1+s2+s3;

Java代码

1. String s1="Who";

2. String s2=" is";

3. String s3=" faster?";

4. String st=s1+s2+s3;

这个时候,String的速度就比不上StringBuffer了。

StringBuffer和StringBuilder

在操作字符串对象,StringBuiler是最快的,StringBuffer次之,String最慢。

Java代码

1. public final class StringBuffer

2. extends AbstractStringBuilder

3. implements java.io.Serializable, CharSequence

4.

5. ublic final class StringBuilder

6. extends AbstractStringBuilder

7. implements java.io.Serializable, CharSequence

Java代码

1. public final class StringBuffer

2. extends AbstractStringBuilder

相关文档
最新文档