
1.18 String、StringBuffer、StringBuilder和StringTokenizer的区别
在Java语言中,有四个类可以对字符或字符串进行操作,分别是String、StringBuffer、StringBuilder和StringTokenizer,其中Character用于单个字符操作,String用于字符串操作,属于不可变类,而StringBuffer也是用于字符串操作,不同之处是StringBuffer属于可变类。
String是不可变类,也就是说String对象一旦被创建,其值将不能被改变,而StringBuffer是可变类,当对象被创建后仍然可以对其值进行修改。由于String是不可变类,因此适合在需要被共享的场合中使用,而当一个字符串经常需要被修改时,最好使用StringBuffer来实现。如果用String来保存一个经常被修改的字符串时,在字符串被修改的时候会比StringBuffer多了很多附加的操作,同时生成了很多无用的对象,由于这些无用的对象会被垃圾回收器来回收,所以会影响程序的性能。在规模小的项目里面这个影响很小,但是在一个规模大的项目里面,这会对程序的运行效率带来很大的影响。
StringBuilder也是可以被修改的字符串,它与StringBuffer类似,都是字符串缓冲区,但StringBuilder不是线程安全的,如果只是在单线程中使用字符串缓冲区,那么StringBuilder的效率会更高些。因此在只有单线程访问的时候可以使用StringBuilder,当有多个线程访问时最好使用线程安全的StringBuffer。因为StringBuffer必要时可以对这些方法进行同步,所以任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
String与StringBuffer另外一个区别在于,当实例化String的时候,可以利用构造方法(String s1=new String("world"))的方式来对其进行初始化,也可以用赋值(String s = "Hello")的方式来初始化,而StringBuffer只能使用构造方法(StringBuffer s=new StringBuffer("Hello"))的方式来初始化。
String字符串修改实现的原理为:当用String类型来对字符串进行修改时,其实现方法是首先创建一个StringBuilder,然后调用StringBuilder的append方法,最后调用StringBuilder的toString方法把结果返回。举例如下:

以上代码等价于下述代码:

由此可以看出,上述过程比使用StringBuilder多了一些附加的操作,同时也生成了一些临时的对象,导致程序的执行效率降低。为了更好地说明这一问题,下面分析一个示例。


程序运行结果为:

从程序的运行结果可以看出,当一个字符串需要经常被修改的时候,使用StringBuilder比使用String的性能要好很多。
在执行效率方面,StringBuilder最高,StringBuffer次之,String最低(StringTokenizer与前三者功能完全不同,故不适合放在一起排序),鉴于这一情况,一般而言,如果要操作的数据量比较小,优先使用String类,如果是在单线程下操作大量数据,优先使用StringBuilder类,如果是在多线程下操作大量数据,优先考虑StringBuffer类。
StringTokenizer是用来分割字符串的工具类,如下例所示:

程序运行结果为:
