StringBuider,StringBuffer,String源码部分方法的比较

1.StringBuider类

StringBuider中append(String)的实现
StringBuider继承自AbstractStringBuilder ,
AbstractStringBuilder中有两个全局属性分别是:

char value[]; //存储字符的数组
int count; //数组中,已经存储字符的个数。(不是数组的长度)

来看一下append(String)的实现:

public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
if (len == 0) return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);//如果容量不够,扩容
str.getChars(0, len, value, count);
count = newCount;
return this;
} 
 



首先要做的是判断value[] 数组的容量是否足够大以容下添加的字符串,如果不够大则扩容。

看一下expandCapacity(int minimumCapacity)函数

void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
} 
 


可以看到,扩容为(原来已经存储字符的个数+1)的两倍,如果溢出,则扩容为Integer的最大值,
如果扩容后的长度仍小于需要的长度,则扩容为需要的长度。
(如果进一步查看copyOf方法,可以看到它最后使用的是一个native方法System.arraycopy() )

回到append(String str);

public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
if (len == 0) return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);//如果容量不够,扩容
str.getChars(0, len, value, count);//把str添加到value[] 数组里面
count = newCount;//更新 已经存储字符的个数属性count
return this;
} 
 



可以看到StringBuilder使用的是一个char类型的数组来存储字符串,一次扩容是根据(已经存储的个数+1)*2来扩容的。并且使用String的getChars方法把新增数组增加到value[]里面,下面来看下StringBuffer类

2.StringBuffer类

可以看到StringBuffer类也是继承AbstractStringBuilder
看一下它的append(String)

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


可以看到除了增加了synchronized没有增加其他东西,它直接引用父类(AbstractStringBuilder)的append(String)方法。再看一下其他方法,发现同样的现象。
也就是说StringBuffer除了方法线程安全之外其他和StringBuider基本一致,并且这两个类都有使用final修饰,也就是说不允许我们进行继承修改。

3.String 类

String类中定义了四个全局属性,暂时关注其中的三个。

private final char value[]; //存储字符的数组
private final int offset;//数组中,第一个存储了字符的位置的index
private final int count;//已经存储的字符个数

这几个全局属性都是final修饰的,并且这些属性是通过构造函数来初始化的,通俗来说,new一个String()出来之后,该String就不可改变了。来看下concat(String)函数

public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
} 
 



可以看到在String类型的字符串后面增加字符串,会new一个新的String返回。这里如果不处理好会发生内存泄露。而StringBuffer和StringBuider的append(String)就不存在这个情况。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值