String和StringBuffer
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
String StringBuffer区别用法
2009-09-26 09:25
String && StringBuffer的区别和用法
2007/02/24 11:02
String && StringBuffer的区别:
非可变对象一旦创建之后就不能再被改变,可变对象则可以在创建之后被改变。String对象是非可变对象;StringBuffer对象则是可变对象。为获得更佳的性能需要根据实际情况小心谨慎地选择到底使用这两者中的某一个。
String类用来表示那些创建后就不会再改变的字符串,它是不可变的(immutable);
StringBuffer类用来表示内容可变的字符串;
例:
1.String对象:
String str = "Hello";
str += "World";
// JVM会创建一个临时的StringBuffer类对象,并调用其append()方法完成字符串的拼接,这是因为 String类是不可变的,拼接操作不得不使用StringBuffer类(并且--JVM会将"Hello"和"World"创建为两个新的 String 对象)。之后,再将这个临时StringBuffer对象转型为一个String,代价不菲!可见,在这一个简单的一次拼接过程中,我们让程序创建了四个对象:两个待拼接的String,一个临时StringBuffer,和最后将StringBuffer转型成为的String--它不是最初的str,而是最初的str的引用指向了新生成的String对象"HelloWorld"。
2.StringBuffer对象:
StringBuffer strBuf = new StringBuffer("Hello");
strBuf.append("World");
// 程序将只产生两个对象:最初的strBuf :"Hello"和拼接时的String ("World"),不再需要创建临时的StringBuffer类对象而后还得将其转换回String对象。节省额外的系统开销。
如何选择是使用String还是StringBuffer:
取决于两种情况,第一种情况是需要连接的字符串是在编译期决定的还是在运行期决定的,第二种情况是你使用的是StringBuffer还是String。
1) 第一种情况:编译期决定相对于运行期决定;如:
String str = "This " + "is " + "a " + "Java " + "program"; StringBuffer strBuf = new StringBuffer();
strBuf.append("This ");
strBuf.append("is ");
strBuf.append("a ");
strBuf.append("Java ");
strBuf.append("program");
此时,+操作符比StringBuffer.append()方法要快,WHY?这里编译器的优化起了关键作用,编译器简单地在编译期连接多个字符串。它使用编译期决定取代运行期决定,在你使用new关键字来创建String对象的时候也是如此。这里
str对象在编译期就决定了而 StringBuffer对象是在运行期决定的。运行期决定需要额外的开销当字符串的值无法预先知道的时候,编译期决定作糜谧址闹悼梢栽は戎赖氖?候,也就是说String str = "This " + "is " + "a " + "Java " + "program";这段代码在编译时,编译器会对程序作出优化,String str被优化成“This is a Java program”;而StringBuffer strBuf只会在运行时才处理。所以效率是不一样的。(注意,这里的String str = "This " + "is " + "a " + "Java " + "program";与 String str = "Hello";
str += "World";是不一样的);
2) 第二种情况:使用StringBuffer取代String
String str = "Hello";
for(int i = 0; i < 40000; i++) {
str += "World";
}
StringBuffer strBuf = new StringBuffer("Hello");
for(int i = 0; i < 40000; i++) {
strBuf.append("World");
}
此时,StringBuffer.append()方法要比+操作符快得多,WHY?原因是两者都是在运行期决定字符串对象,但是+操作符使用不同于StringBuffer.append()的规则;它是通过String和StringBuffer来完成字符串的连接操作的。
另外,在使用StringBuffer时,可以通过StringBuffer的构造函数来设定它的初始化容量,这样可以明显地提升性能。这里提到的构造函数是StringBuffer(int length),length参数表示当前的StringBuffer能保持的字符数量。如:
(1)StringBuffer strBuf = new StringBuffer();
for(int i = 0; i < 40000; i++) {
strBuf.append("Hello");
}
(2)StringBuffer strBuf = new StringBuffer(100000);
for(int i = 0; i < 40000; i++) {
strBuf.append("Hello");
}
此时,(2) 的效率好于 (1),因为StringBuffer内部实现是char数组,当使用缺省的构造函数来创建StringBuffer对象的时候,因为没有设置初始化字符长度,StringBuffer的容量被初始化为16个字符,也就是说缺省容量就是16个字符。当StringBuffer达到最大容量的时候,它会将自身容量增加到当前的2倍再加2,也就是(2*旧值+2)。如果使用缺省值,初始化之后接着往里面追加字符,在追加到第16个字符的时候它会将容量增加到 34(2*16+2),当追加到34个字符的时候就会将容量增加到70(2*34+2)。无论何事只要StringBuffer到达它的最大容量它就不得不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍。所以总是给StringBuffer设置一个合理的初始化容量值是错不了的,这样会带来立竿见影的性能增益。(2)避免了复制数组的开销。