StringBuffer和StringBuilder
文章资料参考:runoob
因为String本身是不可更改的。当你进行以下操作时:
String a = "我爱中国";
int code = a.hashCode();
a = "我深爱中国";
int code2 = a.hashCode();
System.out.println(code);//776638640
System.out.println(code2);//-1717605791
System.out.println(code==code2);//false
code和code2的hashcode完全不同,表示这两个字符串是不同的引用,所以对字符串a进行再次赋值时,内存会重新创建一个新的字符串,让a重新指向内存中这个新的字符串。
StringBuffer和StringBuilder正是弥补了String不能修改内容的这一缺点。和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
上图是Stringbuffer和stringbuilder的继承关系。
StringBuffer
Stringbuffer是一个可变的字符序列。 字符串缓冲区类似于String ,但可以进行修改。 在任何时间点它都包含一些特定的字符序列,但序列的长度和内容可以通过某些方法调用来改变。
字符串缓冲区可供多个线程使用。 这些方法在必要时进行同步,以便任何特定实例上的所有操作都表现得好像它们以某个串行顺序出现,这与所涉及的每个单独线程所进行的方法调用的顺序一致。
StringBuffer上的主要操作是append和insert方法,它们被重载以接受任何类型的数据。 每个都有效地将给定的数据转换为字符串,然后将该字符串的字符追加或插入字符串缓冲区。 append方法总是在缓冲区的末尾添加这些字符; insert方法在指定点添加字符。
一般情况下,如果某人是指的一个实例StringBuffer ,然后sb.append(x)具有相同的效果sb.insert(sb.length(), x) 。
从JDK 5版本开始,这个类已经补充了一个设计用于单个线程的等效类, StringBuilder 。 通常应优先使用StringBuilder类,因为它支持所有相同的操作,但速度更快,因为它不执行同步。
创建StringBuffer对象
//默认的初始长度为16个字符长度。
StringBuffer s1 = new StringBuffer();
//显示定义长度为15个字符长度
StringBuffer s2 = new StringBuffer(15);
//长度为str.length() + 16
StringBuffer s3 = new StringBuffer("str");
//追加字符串
s1.append("china");
Stringbuffer中的常见方法
public StringBuffer append(String s)
作用:在StringBuffer的后面追加字符串
举例:
StringBuffer s1 = new StringBuffer();
String s = "china";
s1.append(s);
System.out.println(s1);//china
public StringBuffer reverse()
作用:将该字符序列顺序反转
举例:
StringBuffer s1 = new StringBuffer();
String s = "china";
s1.append(s);
s1.reverse();
System.out.println(s1);//anihc
public delete(int start, int end)
作用:删除指定区间的子序列
举例:
StringBuffer s1 = new StringBuffer("123456789");
s1.delete(3,4);
System.out.println(s1);//12356789
【知识扩展】:
//AbstractStringBuilder.java中的源码
public AbstractStringBuilder delete(int start, int end) {
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (end > count)
end = count;
if (start > end)
throw new StringIndexOutOfBoundsException();
int len = end - start;
if (len > 0) {
System.arraycopy(value, start+len, value, start, count-end);
count -= len;
}
return this;
}
从源码中可以看出,当start小于0或者start>end时,会产生StringIndexOutOfBoundsException异常。而end值如果超出了这个序列的容量,那么它会自动帮你修改为这个序列的最大长度count。条件中的len如果等于0,即start等于end那么删除就不会执行,原来的字符序列也不会进行改变。
public insert(int offset, int i)
作用:将int参数的字符串形式插入到指定位置后面。
举例:
StringBuffer s1 = new StringBuffer("地球");
s1.insert(1, 100);
System.out.println(s1);//地100球
insert(int offset, String str)
作用:将指定字符串插入到指定位置后面。
举例:
StringBuffer s1 = new StringBuffer("地球");
s1.insert(1, "上的篮");
System.out.println(s1);//地上的篮球
replace(int start, int end, String str)
作用:替换指定位置的子字符串
StringBuffer s1 = new StringBuffer("123456789");
s1.replace(1, 3, "世界");
System.out.println(s1);//1世界456789
其他方法:StringBuffer类API
Stringbuilder
StringBuilder的构造方法和常用方法与StringBuffer大同小异,因此在这里就不列举了,具体查看:StringBuilder类API
StringBuffer和StringBuilder的区别
Stringbuffer的线程安全,可变的字符序列。 字符串缓冲区类似于String ,但可以进行修改。 字符串缓冲区可供多个线程使用。 这些方法在必要时进行同步,以便任何特定实例上的所有操作都表现得好像它们以某个串行顺序出现,这与所涉及的每个单独线程所进行的方法调用的顺序一致。
StringBuilder类,它支持与Stringbuffer所有相同的操作,但速度更快,因为它不执行同步。