是 String , StringBuffer 还是 StringBuilder ?

[复制链接]
查看11 | 回复4 | 2007-1-24 12:56:49 | 显示全部楼层 |阅读模式
相信大家对 String 和 StringBuffer 的区别也已经很了解了,但是估计还是会有很多同志对这两个类的工作原理有些不清楚的地方,今天我在这里重新把这个概念给大家复习一下,顺便牵出 J2SE 5.0 里面带来的一个新的字符操作的类—— StringBuilder (先别忙着扔我砖头,我还算清醒,我这里说的不是 C #, Java 也有 StringBuilder 类)。那么这个 StringBuilder 和 StringBuffer 以及我们最早遇见的 String 类有那些区别呢?在不同的场合下我们应该用哪个呢?我讲讲自己对这几个类的一点看法,也希望大家提出意见,每个人都有错的地方,在错了改的同时更是一个学习的好机会。
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象(为什么?问问 Java 的设计者吧,为什么 String 不是原生类型呢?)因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。这里尝试举个不是很恰当的例子:
String S1 = “abc”;
For(int I = 0 ; IString
而 StringBuilder 跟他们比又怎么样呢?先简单介绍一下, StringBuilder 是 JDK5.0 中新增加的一个类,它跟 StringBuffer 的区别看下面的介绍(来源 JavaWorld ):
Java.lang.StringBuffer 线程安全的可变字符序列。类似于 String 的字符串缓冲区,但不能修改。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5.0 开始,为该类增添了一个单个线程使用的等价类,即 StringBuilder 。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。
但是如果将 StringBuilder 的实例用于多个线程是不安全的。需要这样的同步,则建议使用 StringBuffer 。
这样说估计大家都能明白他们之间的区别了,那么下面我们再做一个一般性推导:
在大部分情况下 StringBuilder > StringBuffer
因此,根据这个不等式的传递定理: 在大部分情况下
StringBuilder > StringBuffer > String
既然有这样的推导结果了,我们做个测试验证一下:
测试代码如下:
public class testssb {

/** Creates a new instance of testssb */
final static int ttime = 10000;// 测试循环次数
public testssb() {
}

public void test(String s){
long begin = System.currentTimeMillis();
for(int i=0;i StringBuffer > String 的了。
其实我这里测试并不是很公平,因为都放在了一起以先后顺序进行,测试方法中间没有考虑到JVM的GC收集前面产生的无引用对象垃圾而对执行过程的中断时间。
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
import java.awt.Graphics;
import java.applet.Applet;
public class SC {
char ChineseArray[] = {'祝','你','生', '日','快', '乐'};
static StringBuffer buffer;
static String s, s1, s2, s3;
public SC() {
s = new String( "您好!" );
buffer = new StringBuffer(s);
buffer.append( " Welcome to Java Home!" );
// 用字符串构造方法
s1 = new String(ChineseArray);
s2 = new String( ChineseArray, 2, 4 );
s3 = "Java 家论坛祝你" + s2;
}
public static void main( String arg[] ) {
SC app = new SC();
System.out.println( "s1 = " + s1 );
System.out.println( "s2 = " + s2 );
System.out.println( "s3 = " + s3 );
System.out.println( "s = " + s );
System.out.println( "buffer = " + buffer);
System.out.println();
for (int i=s1.length() - 1; i>=0; i--)
System.out.print( String.valueOf( s1.charAt(i)));
System.out.println();
for (int i=buffer.length() - 1; i>=0; i--)
System.out.print( String.valueOf( buffer.charAt(i)));
System.out.println();
System.out.println( "buffer 长度是 " + buffer.length());
}
}
---------------------
输出:
$ java SC
s1 = 祝你生日快乐
s2 = 生日快乐
s3 = Java 家论坛祝你生日快乐
s = 您好!
buffer = 您好! Welcome to Java Home!
乐快日生你祝
!emoH avaJ ot emocleW !好您
buffer 长度是 25
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
受教,谢谢楼主!
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
GOOD!
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
不错啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行