在解决这个问题之前,需要了解的内容:
1、String是只读字符串,即String引用的字符串内容是不可改变的。
1 String s1 = "abc"; 2 s1 = "def"; //“abc”并没有改变,只是s1的指向改变了,原来的“abc”字符串变为了一个不可及对象
2、StringBuffer/StringBuilder 表示的字符串对象可以直接进行修改。
3、StringBuilder 是 Java5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,
因为它的所有方法都没有被 synchronized 修饰,因此它的效率理论上也比 StringBuffer效率高。
接下来进入正题,解决效率的问题:
1 String s = "abc" + "def";
上面的代码在一般的开发中会被常常用到,但是这样做好不好,当然也不能简单的说好或者不好。分情况来看:
1、从效果上来看,两者是完全等效的。如果需要拼接的字符串并不是很多,可以使用“+”,因为代码量少,例如上面的代码。
2、从运行效率和资源消耗方面来讲,两者存在着很大的区别。
来看一段代码:
1 String s = ""; 2 Random r = new Random(); 3 for (int i = 0;i < 10;i++) { 4 s = s + r.nextInt(1000) + " "; 5 }
将上面的代码反编译之后,会看到编译器其实在每次循环中都是将“+”转化为StringBuilder对象,进行append。循环中的代码反编译的结果如下:
s = (new StringBuilder(String.valueOf(s))).append(rand.nextInt(1000)).append(" ").toString();
虽然 Java 有垃圾回收器,但这个回收器的工作时间是不定的。如果不断产生这样的垃圾,那么仍然会占用
大量的资源。解决这个问题的方法就是在程序中直接使用 StringBuilder 来连接字符串。代码如下:
1 String s = ""; 2 Random r = new Random(); 3 StringBuilder sb = new StringBuilder(); 4 for(int i = 0; i < 10; i++){ 5 sb.append(r.nextInt(1000)); 6 sb.append(" "); 7 }
最后需要注意的是:“+”和StringBuilder不要混着用,否则,会创建更多的StringBuilder对象。
在这里,StringBuffer和StringBuilder的用法基本一样,后者是JDK5之后出来的,线程不安全,但是效率高。