这两天在写一道题,题目如下:
给出一个String字符串:The sky is blue
输出:blue is sky The
这道题可以用下边两种方法来实现:
第一种方式:用String类型的返回值
public String reverseStr(String str){
if(str.length < 1)
return null;
String strList = str.split(" ");
String result = new String();
for(int i=strList.length-1;i>0;i--){
result = result + strList[i] + " ";
}
result = result + strList[0];
return result;
}
另外一种方式:用StringBuffer类型的返回值
public StringBuffer reverseStr(String str){
if(str.length < 1)
return null;
String strList = str.split(" ");
StringBuffer result = new StringBuffer();
for(int i=strList.length-1;i>0;i--){
result = result.append(strList[i]).append(" ");
}
result = result.append(strList[0]);
return result;
}
那么既然String和StringBuffer类型都可以解决这种问题,那我们为什么会有StringBuffer这个东西呢?
String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
反观开头的题目,
result = result + strList[i] + " ";
这行代码,result是一个String对象的引用,strList[i]是另一个String对象的引用,当二者相加时,会生成新的String对象,而不是在result引用的对象中扩展内存。
而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “The” + “ sky” + “ is” + " blue";
StringBuffer Sb = new StringBuilder(“The”).append(“ sky”).append(“ is”).append(" blue");
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
String S1 = “The” + “ sky” + “ is” + " blue"; 其实就是:
String S1 = “The sky is blue”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了。