本帖最后由 宋浩 于 2012-6-13 13:36 编辑
String对象内容是不可改变的,StringBuffer是可以改变的,并且高效。
首先,请看下面的代码
StringString str = "hello";
str=str+"world";
上面两句,虽然str的值最终改变了,但是实际上在编译的时候,第一句str是一个对象,被分配了一个地址,第二句执行时,原来的str被释放,然后重新分配。
str原本指向一 String object instance ("hello"), a + "world" 会造出另一新的 String object instance ("helloworld"), 然后
str再指向这新的 String instance。
StringBufferStringBuffer str2 = new StringBuffer("hello");
str2.append("world");
在这个过程中,只存在str2这么一个对象,str2一直都指向一个 StringBuffer instance。str2.append 也只是改变此 instance 的内容而已。
在我以前的了解中,String是一个final Class, StringBuffer不是。所以对于
String a = "abc"; String b = "def"; String c = a + b ;
存在一个对象拷贝构造和解析的消耗问题;对于一个StringBuffer来说,
StringBuffer sb = new StringBuffer();
sb.append("abc") ;
sb.append("def");
因为StringBuffer是一个可以实例化的类,而且它的内建机制
是维护了一个capacity大小的字符数组,所以它的append操作不存在对象的消耗问题,所以我
得如果存在String连接这种事情,StringBuffer来做会好很多。但事情并不是这么简单,看下面代码
String string1 = "abc" + "def" + "ghi" + "jkl";
StringBuffer sb = new StringBuffer();
sb.append("abc") ;
sb.append("def");
sb.append("ghi") ;
sb.append("jkl");
String string2 = sb.toString();
如前面所说,Sting的"+"运算肯定比StringBuffer的append()效率低,但经过测试不是这样,为什么?
这里,我们需要理解程序过程的两个时期,一个是编译时,一个是运行时,在编译时,
编译器会对你的程序做出优化,所以String会被优化成"abcdefghijkl",而的StringBuffer只会在运行时才处理。
所以效率是不一样的。
如果代码是这样的:
String str1;
for(int i = 0; i< 100000;i++){
str1+= String.valueOf(i) ;
}
StringBuffer sb = new StringBuffer();
for(int i = 0; i< 100000;i++){
sb.append(i) ;
}
String str2 = sb.toString();
如果是这种情况的话,String的效率就大大不如StringBuffer,区别在哪里?就在于运行时和编译时的优化问题上了!
|