七、字符串生成器
创建成功的字符串对象,其长度是固定的,内容不能被改变和编译。虽然使用“+”可以达到附加新字符或字符串的目的,但“+”会产生一个新的String实例,会在内存中创建新的字符串对象。如果重复地对字符进行修改,将极大地增加系统开销。而J2SE5.0新增了可变的字符序列String Builder类,大大提高了频繁增加字符串的效率 。
下面介绍下String、StringBuffer、StringBuilder三者的区别与联系:
1.三者在执行速度方面的比较:StringBuilder > StringBuffer > String
2.String <(StringBuffer,StringBuilder)的原因
String:字符串常量
StringBuffer:字符串变量
StringBuilder:字符串变量
从上面的名字可以看到,String是“字符串常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:
String s = "abcd";
s = s+1;
System.out.print(s);// result : abcd1
我们明明就是改变了String型的变量s的,为什么说是没有改变呢? 其实这是一种欺骗,JVM是这样解析这段代码的:首先创建对象s,赋予一个abcd,然后再创建一个新的对象s用来执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多低了。
而StringBuffer与StringBuilder就不一样了,它们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,当然速度就快了。
案例代码:
public class Jerque{
public static void main(String args[]){
String str ="";
//定义对字符串执行操作的起始时间
long startTime = System.currentTimeMillis();
for(int i = 0; i<10000; i++){
str = str +i;
//利用for循环执行10000次操作,并循环追加字符串
}
long endTime = System.currentTimeMillis();
long time = endTime- startTime;
System.out.println("String消耗的时间:"+time);
StringBuilder builder = new StringBuilder("");
startTime = System.currentTimeMillis();
for(int j = 0; j <10000; j++){
builder.append(j);
}
endTime = System.currentTimeMillis();
time = endTime -startTime;
System.out.println("StringBuilder消耗的时间:"+time);
}
}
结果为:
String消耗的时间:408
StringBuilder消耗的时间:1
通过这一实例可以看出,两种操作的执行的时间差距很大。如果在程序中频繁的附加字符串,建议使用StringBuilder。新创建的StringBuilder对象初始容量是16个字符,可以自行指定初始长度。如果附加的字符超过可容纳的长度,则StringBuilder对象将自动增加长度以容纳被附加的字符。
StringBuffer常用方法
(由于StringBuffer和StringBuilder在使用上几乎一样,所以只写一个,以下部分内容网络各处收集,不再标注出处)
StringBuffer s = new StringBuffer();
这样初始化出的StringBuffer对象是一个空的对象,
StringBuffer sb1=new StringBuffer(512);
分配了长度512字节的字符缓冲区。
StringBuffer sb2=new StringBuffer(“how are you?”)
创建带有内容的StringBuffer对象,在字符缓冲区中存放字符串“how are you?”
若要使用StringBuilder最后输入字符串的结果,可使用toString()方法。利用StringBuilder类中的方法可动态地执行添加、删除和插入等字符串的编辑操作。该类的常用方法如下:
(1)append()方法
该方法用于向字符串生成器中追加内容。通过该方法的多个重载形式,可实现接受任何类型的数据,如int boolean char String double或者另一个字符串生成器等。
语法:
append(content);
其中,content表示要追加到字符串生成器中的内容,可以是任何类型的数据或者其他对象。
(2)insert(int offset,arg)方法
该方法用于向字符串生成器中的指定位置插入数据内容。通过该方法的不同重载形式,可实现向字符串生成器中插入int float char和boolean等基本数据类型或其他对象。
语法:
insert(int offset,arg);
offset:表示字符串生成器的位置。该参数必须大于等于0,且小于等于此序列的长度;
arg:表示将插入至字符串生成器的位置。该参数可以是任何的数据类型或其他对象;
案例代码:
StringBuilder bf = new StringBuilder("hello");
bf.insert(5,"word");
System.out.println(bf.toStirng());
结果:
helloword
(3)delete(int start,int end)方法
移除此序列的子字符串中的字符。该子字符串从指定的start处开始,一直到索引end-1处的字符。如果不存在这种字符,则一直到序列尾部。
如果start 等于end,则不发生任何更改。
语法:
delete(int start,int end);
start:表示将要删除的字符串的起点位置;
end:表示将要删除的字符串的终点位置。
案例代码:
StringBuiler bf = new StringBuilder("StringBuilder");
bf.delete(5,10);
System.out.println(bf.toString());
结果:
Strinder
(4)deleteCharAt方法
public StringBuffer deleteCharAt(int index)
该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“KMing”);
sb. deleteCharAt(1);
该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变 为”King”。
还存在一个功能类似的delete方法:
public StringBuffer delete(int start,int end)
该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb. delete (1,4);
该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。
(5)reverse方法
public StringBuffer reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.reverse();
经过反转以后,对象sb中的内容将变为”cba”。
(6)setCharAt方法
public void setCharAt(int index, char ch)
该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.setCharAt(1,’D’);
则对象sb的值将变成”aDc”。
(7)trimToSize方法
public void trimToSize()
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费,和String的trim()是一样的作用,不在举例。
(8)length方法
该方法的作用是获取字符串长度.
(9)setlength方法
该方法的作用是设置字符串缓冲区大小。
StringBuffer sb=new StringBuffer();
sb.setlength(100);
如果用小于当前字符串长度的值调用setlength()方法,则新长度后面的字符将丢失。
(10)sb.capacity方法
该方法的作用是获取字符串的容量。
StringBuffer sb=new StringBuffer(“string”);
int i=sb.capacity();
(11)ensureCapacity方法
该方法的作用是重新设置字符串容量的大小。
StringBuffer sb=new StringBuffer();
sb.ensureCapacity(32); //预先设置sb的容量为32
(12)getChars方法
该方法的作用是将字符串的子字符串复制给数组。
getChars(int start,int end,char chars[],int charStart);
StringBuffer sb = new StringBuffer("I love You");
int begin = 0;
int end = 5;
//注意ch字符数组的长度一定要大于等于begin到end之间字符的长度
//小于的话会报ArrayIndexOutOfBoundsException
//如果大于的话,大于的字符会以空格补齐
char[] ch = new char[end-begin];
sb.getChars(begin, end, ch, 0);
System.out.println(ch);
结果:I lov