StringBuilder:
可变字符串,线程不安全,但是效率高。
StringBuilder sb = new StringBuilder();//默认字符数组长度为16
StringBuilder sb = new StringBuilder(32); //可以自定义长度
StringBuilder常用的函数:
append
例如:
sb.append(true).append(321).appen(“ssssss”);//这可以形成一个方法链(通过return this.)
append方法源码最后是return this.这是可以形成方法链的一个主要的原因。append方法最后return this,故sb.append(true)最后返回的也是sb对象,然后sb.append(321)返回的还是sb对象,然后sb.append(“ssssss”)最后返回的还是sb对象。
append中还自带扩容机制。
delete
public StringBuilder delete(int start, int end) 也可以写成方法链。
length
public int length()
返回字符串的长度
capacity
public int capacity()
不同于length,返回的是当前的容量,最多可以容纳多少个字符
replace
public StringBuilder replace(int start, int end, String str)
替换方法是从start 开始 end结束之间插入字符串。
StringBuffer:
可变字符串,线程安全,效率相对较低。
除了线程安全与否以及效率高低基本和StringBuilder差不多。
常用的函数有:
StringBuffer s = new StringBuffer();
这样初始化出的StringBuffer对象是一个空的对象,
StringBuffer sb1=new StringBuffer(512);
分配了长度512字节的字符缓冲区。
StringBuffer sb2=new StringBuffer(“how are you?”)
创建带有内容的StringBuffer对象,在字符缓冲区中存放字符串“how are you?”
append
public StringBuffer append(boolean b)
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接,调用该方法以后,StringBuffer对象的内容也发生改 变,例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.append(true);
则对象sb的值将变成”abctrue”
使用该方法进行字符串的连接,将比String更加节约内容,经常应用于数据库SQL语句的连接。
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”。
insert
public StringBuffer insert(int offset, boolean b),
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,false);
该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。
reverse
public StringBuffer reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.reverse();
经过反转以后,对象sb中的内容将变为”cba”。
setCharAt
public void setCharAt(int index, char ch)该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.setCharAt(1,’D’);
则对象sb的值将变成”aDc”。
trimToSize
public void trimToSize()
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费,和String的trim()是一样的作用,不在举例。
length
该方法的作用是获取字符串长度 ,不用再说了吧。
setlength
该方法的作用是设置字符串缓冲区大小。
StringBuffer sb=new StringBuffer();
sb.setlength(100);
如果用小于当前字符串长度的值调用setlength()方法,则新长度后面的字符将丢失。
capacity
该方法的作用是获取字符串的容量。
StringBuffer sb=new StringBuffer(“string”);
int i=sb.capacity();
ensureCapacity
该方法的作用是重新设置字符串容量的大小。
StringBuffer sb=new StringBuffer();
sb.ensureCapacity(32); //预先设置sb的容量为32
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
String:
它们都有char[]数组来保存字符串的字符,但是
StringBuilder中的char[] value是default的,是可变的
String中的char[] value是private final类型的,是不可变的,不提供接口。
关于String对象的存储问题
举个例子:
String str1 = new String(“abcd”);——>char[] value = {‘a’,’b’,’c’,’d’};
String str2 = “def”; ——>置于常量池中 “def”
String str3 = new String(“abcd”);
String str4 = “def”;
str1.equals(str3); —> true
str1 == str3; —> false;
由于String的euqals比较的是内容,所以是true
而==比较的是两者的地址,故答案为false;
str2.equals(str4); —> true
str2 == str4; —> true;
由于str2与str4都指向常量池里面的”def”对象,所以二者无论是内容还是地址都是一致的。
举个例子:
String str = “hello”;
str = str + 1;
通过这个例子很多人就会产生疑问,不是说String不可变吗,为什么我们把它的内容改变了呢?
JVM实际上是这样解析这段代码的,首先我们创建了str对象来存”hello”,然后再创建一个新的对象str来执行第二句代码,即我们之前的str并没有发生改变,jva重新创建了一个相同名字的str来覆盖我们之前的str,所以说String对象是不可变的。基于这样子的机制,我们每次对String进行操作的时候,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被gc给回收掉,这样子的话执行效率自然就很低了。
但是存在一个很特殊的例子:
其实就是str = “Hello,every!my name is vivian”;
所以不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了,例如:
String str1 = “Hello,every!”;
String str2 = “my name is”;
String str3 = “vivian”;
String str = str1 + str2 + str3;
StringBuilder与StringBuffer
StringBuilder:线程非安全的
StringBuffer:线程安全的
当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。
总结:
1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区下操作大量数据 = StringBuffer