再谈String和StringBuffer
String类的缺点
String 是常量,其对象一旦创建完毕就无法改变。当使用+拼接字符串时,会生成新的 String 对象,而不是向原有的 String 对象追加内容。
例如:
String str = “hello”;
str = str +” world”;
在上面这个程序中第一句会在StringPool中产生一个内容为“hello”的对象,关键是第二句,这句话并非是在原字符串的基础上添加,而是在堆和池中新建了一个字符串。这样就产生两个字符串,所以当我们使用String时就会占用许多不必要的空间,为了解决这个问题我们引入了另一个类StringBuffer类。
可以改变的字符串:StringBuffer
因为在Java中最常用的就是字符串,而String类型如果多次使用就会占用大量的空间,会严重影响程序运行的实际时间。所以我们需要一个可以改变的字符串:StringBuffer。
我们先看看他的构造方法:
public StringBuffer();
构造一个空的字符串,初始容量为 16 个字符。我们从源码看看他是怎么做的。
public StringBuffer() {
super(16);
}
这样的话我们就看看他的父类的构造方法,他继承了AbstractStringBuilder类。
构造方法如下:
AbstractStringBuilder(intcapacity) {
value = new char[capacity];
}
这样我们就明白了他是创建了一个长度为16的字符数组。
下面我们来讲一下他的方法,先讲添加吧。
1.publicStringBuffer append(Objectobject)
在Java类库中这个方法被重载了15次,其实大家没必要都看,都是一个意思,就是参数不一样,就是将你传人的参数转换为字符串,任何添加在原字符串后面。在这里我说一句,若是要使用StringBuffer对象的内容,需要调用toString()方法,例:
StringBuffer buffer = newStringBuffer();
buffer.append(100);
String str =buffer.toString();
此时Str的内容就是一个字符串”100”。
2.publicStringBuffer insert(intoffset,Objectobject)
这个方法的作用是在指定位置添加一个字符串,这个offset是指要插入的位置。
他的源码是这么写的:
publicsynchronized StringBufferinsert(int offset, String str) {
super.insert(offset, str);
returnthis;
}
看来又要看他的父类在的方法了:
public AbstractStringBuilder insert(intoffset, String str) {
if((offset < 0) || (offset > length()))
throw newStringIndexOutOfBoundsException(offset);
if(str == null)
str = "null";
intlen = str.length();
intnewCount = count + len;
if(newCount > value.length)
expandCapacity(newCount);
System.arraycopy(value, offset, value, offset + len, count - offset);
str.getChars(value, offset);
count = newCount;
returnthis;
}
在这个方法中他首先判断了一下输入的位置是否符合逻辑(不能小于0,不能大于最大的位置,否则抛出异常)。然后看输入的是否是空(null),再计算一下传人的字符串的长度,再加上原字符串的长度,算出新字符串的长度,如果大于容量(初始容量为16)就调用了
expendCapacity()方法,这个方法的源码如下:
void expandCapacity(intminimumCapacity) {
intnewCapacity = (value.length +1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
他是先将原容量加一乘二与新长度比较,如果大于新长度就拿这个数作为新容量,如果小于新容量就将新长度作为新字符串的容量。
说到这里这个方法的实现大家应该就明白了
3.publicStringBuffer delete(intstart,int end)
有添加就肯定有删除的,这个方法中的start和end分别表示了要删除的起始位置和终结位置。
关于StringBuffer我就说这么多吧。