`
cjsmq
  • 浏览: 14278 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java StringBuffer StringBuilder

阅读更多
java StringBuffer StringBulider

StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)

String 类型和 StringBuffer 、StringBuilder 类型的主要性能区别其实在于 String 是不可变的对象,而后俩者都是可变的。

来看看 StringBuffer类源码定义:

 
public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    public StringBuffer() {
	super(16);
    }

     public StringBuffer(int capacity) {
	super(capacity);
    }


上例代码我们发现 StringBuffer 继承了 AbstractStringBuilder抽象类。包括构造方法的实现,都是父类提供的。

然后,我们打开 StringBuilder源码定义:

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    public StringBuilder() {
	super(16);
    }

    public StringBuilder(int capacity) {
	super(capacity);
    }

我们发现两者都继承了AbstractStringBuilder抽象类。且构造方法都调用父类实现。

我们接着看两者append方法实现:

先看StringBuffer的:

   
 public synchronized StringBuffer append(Object obj) {
        super.append(String.valueOf(obj));
        return this;
    }

    public synchronized StringBuffer append(String str) {
        super.append(str);
        return this;
    }
    //...


再看StringBuilder的:
    
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    //...


对比上面两段源码 我们发现 StirngBuffer 和StringBuilder的 append实现都是调用父类实现的。唯一不同的是 StringBuffer是线程安全的,方法中多了synchronized ,而StringBuilder 是非线程安全的。

我们看下父类AbstractStringBuilder 定义 及 append 实现:

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    //底层与String类一样都是 char类型数组。
    char value[];
    //字符串长度
    int count;

    AbstractStringBuilder() {
    }

    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }


    
    public AbstractStringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }
    
    public AbstractStringBuilder append(String str) {
        //对于str==null的
        if (str == null) str = "null";
        int len = str.length();
        if (len == 0) return this;
        //新的字符串长度
        int newCount = count + len;
        if (newCount > value.length)
             //当新的字符串长度比原先数组长度大时,需要对char 数组扩容。
               expandCapacity(newCount);
        //将新添的数据追加到char类型数组中。
         str.getChars(0, len, value, count);
        count = newCount;
        return this;
    }
    
    //数组扩容 
    void expandCapacity(int minimumCapacity) {
        //先扩容成 (原先的长度+1)*2
        int newCapacity = (value.length + 1) * 2;
        //判断newCapacity值是否满足要求
         //如果新的长度还是不够,则直接取值 minimumCapacity 
        if (newCapacity < 0) {
           newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
           newCapacity = minimumCapacity;
        }	
        char newValue[] = new char[newCapacity];
        //将原先的数据拷贝到新的char 数组中。
         System.arraycopy(value, 0, newValue, 0, count);
        value = newValue;
    }

     public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > count) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }
        System.arraycopy(value, offset + srcBegin, dst, dstBegin,
             srcEnd - srcBegin);
    }



分享到:
评论
1 楼 在世界的中心呼喚愛 2012-06-01  
很清晰的解释,注意到队列,现在对stringbuffer和stringbuilder的append方法有更多理解

相关推荐

Global site tag (gtag.js) - Google Analytics