String、StringBuffer、StringBuilder
1.String、StringBuffer、StringBuilder 三者异同
-
继承关系
-
String : 不可变字符序列。底层使用char[ ]存储(声明为final,所以不可变)
-
StringBuffer :可变字符序列。线程安全但是效率低。底层使用char[ ]存储
-
StringBuilder(JDK5新增) :可变字符序列。线程不安全但是效率高。底层使用char[ ]存储
-
效率测试
public static void main(String[] args)
{
String str = "";
StringBuffer buffer = new StringBuffer("");
StringBuilder builder = new StringBuilder("");
long startTime = System.currentTimeMillis();
for (int i = 0; i < 30000; i++)
{
buffer.append(String.valueOf(i));
}
long endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 30000; i++)
{
builder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 30000; i++)
{
str = str + i;
}
endTime = System.currentTimeMillis();
System.out.println("String的执行时间:" + (endTime - startTime));
}
StringBuffer的执行时间:10
StringBuilder的执行时间:4
String的执行时间:792
2.String、StringBuffer、StringBuilder 源码分析
- String
String str = new String(); //char[] value = new char[0];
String str = new String("abc"); //char[] value = new char[]{'a','b','c'};
- StringBuffer / StringBuilder(二者类似)
StringBuffer buffer1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度是16的数组。
buffer1.append('a');//value[0] = 'a';
buffer1.append('b');//value[1] = 'b';
StringBuffer buffer2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];底层创建了长度为length+16 的数组
注意:虽然StringBuffer buffer=new StringBuffer( ) 在底层创建了长度为16的数组,但是调用buffer.length() 返回的是实际长度(即 0)
3.StringBuffer / StringBuilder 扩容
3.1为何会扩容
new StringBuffer( )底层创建了长度为16的数组。 new StringBuffer(“abc”) 底层创建了长度为 “abc”.length()+16的数组。 但是当在字符串末尾添加的字符长度超过16时就需要将数组扩容。
3.2如何扩容
(1)调用buffer.append()的时候会对当前容量进行判断
(2) 确定下需要的最小的容量 (当前字符串长度+要添加的字符串长度) 是否大于当前char数组的长度,如果大于就扩容
(3) 判断扩容当前 char数组长度的2倍+2 的长度是否满足扩容需求。
若满足则扩容后将原有数组中的元素复制到新的数组中。
若不满足则设置为当前字符串长度+要添加的字符串长度,判断append扩容是否超过MAX_ARRAY_SIZE,如果是则抛出异常 OutOfMemoryError
4.StringBuffer / StringBuilder常用函数
StringBuffer append() 将指定字符串追加到此字符序列。
StringBuffer delete(int start,int end) 删除指定位置的内容
StringBuffer replace(int start, int end, String str) 把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() 逆转当前字符序列
public int indexOf(String str) 返回第一次出现的指定子字符串在该字符串中的索引
public String substring(int start,int end) 返回从start开始到end索引结束的左闭右开区间的子字符串
public int length() 返回长度
public char charAt(int n ) 返回此序列中指定索引处的 char 值
public void setCharAt(int n ,char ch) 更改指定位置处的char字符