StringBuilder,StringBuffer的深入了解

StringBuilderStringBuffer 相对于String来说可以被多次修改而不会产生新的对象,而StringBuilderStringBuffer最大的不同就是在于StringBuilder的方法不是线程安全的(不能同步访问)。我们以StringBuilder为例:

StringBuilder可以被多次修改而不会产生新的对象可以从源码分析为什么:

StringBuilder对于变量的修改主要用了方法append(String),以append方法为例来分析:而StringBuilder继承了 AbstractStringBuilder类实现了Serializable, CharSequence,append方法调用了父类AbstractStringBuilderappendappend(String paramString)方法,该方法如下所示:

  public AbstractStringBuilder append(StringparamString)
  {
    if (paramString == null) {
      paramString = "null";
    }
    int i = paramString.length();
    if (i == 0) {
      return this;
    }
    int j = this.count + i;
    if (j > this.value.length) {
      expandCapacity(j);
    }
    paramString.getChars(0, i, this.value,this.count);
    this.count = j;
    return this;
  }


分析代码可以得到当传入的paramString为空的时候直接返回原来的值,如果不为null则获取this.count+ paramString.length()也就是合并的总长度,在判断是否大于以前this字符串的长度,大于调用expandCapacity(j)方法如下:

void expandCapacity(int paramInt)
 {
   int i = (this.value.length + 1) * 2;
   if (i < 0) {
     i = 2147483647;
   } else if (paramInt > i) {
     i = paramInt;
   }
   this.value = Arrays.copyOf(this.value, i);
 }


定义int变量i并赋值为原来字符长度2倍+2,如果长度小于0则将i赋值为int的最大值2^31-1,如果不小于0(一般都不小于0)合并总长度大于原来字符长度+2的话则将i的值变为合并的总长度值,最后调用Arrays.copyOf复制数组并扩建字符数组的长度为i,并赋值赋值给以前的字符串this;此方法的目的就是对以前字符数组进行扩容以此有足够的空间来添加新的字符串且不改变原来的对象还是this

 

接着看上面的append方法调用paramString.getChars(0, i, this.value, this.count)而此方法源码如下:

  

public void getChars(int paramInt1, intparamInt2, char[] paramArrayOfChar, int paramInt3)
  {
    if (paramInt1 < 0) {
      throw newStringIndexOutOfBoundsException(paramInt1);
    }
    if ((paramInt2 < 0) || (paramInt2 >this.count)) {
      throw newStringIndexOutOfBoundsException(paramInt2);
    }
    if (paramInt1 > paramInt2) {
      throw newStringIndexOutOfBoundsException("srcBegin > srcEnd");
    }
    System.arraycopy(this.value, paramInt1,paramArrayOfChar, paramInt3, paramInt2 - paramInt1);
  }

其实就是实现了一个System.arraycopy(src,srcPos, dest, destPos, length)方法,System.arraycopy其实是java的一个调用别的语言的本地接口,它会实现元对象src截取从srcPos位置开始到srcPos+length长度这段对象内容复制到目标对象destdest的放置位置destPos开始赋值的一个复制方法,它也可以自己对自己进行复制赋值,

这是对象内容修改而不改变的关键,我们分析传进来的参数

this.value就是paramString.value(paramString调用的getChars方法此处的this不同上面的this.value)

paramInt1源对象要复制的起始位置为0

paramArrayOfChar为以前的对象this.valuethis.value千万别搞混了)

paramInt3以前对象this的长度count

paramInt2 - paramInt1(也就是i)以前对象this放置的起始位置为ithis的末尾开始

根据上面的参数来看次方发就是将要appendString对象paramString复制并拼接赋值到扩容后的源this对象以此来实现修改对象的append操作并不改变原来的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值