1. String、StringBuffer、StringBuilder三者的异同?
- String:不可变的字符序列;底层使用char[]存储
- StringBuffer:可变的字符序列;线程安全的,效率低 (因为使用了synchronized) ;底层使用char[]存储
- StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
2. StringBuffer类:
其可变的字符序列体现在:
- 例如下面示例,对于String,因为储存在final的char[]中,具有不可变性。其常用方法都是直接返回一个新的String对象,原本的对象不会改变。
- 但是StringBuffer类型的对象,其setCharAt()方法是void的,直接可以在原储存区域更改该对象某个位置的值。
- 注意声明StringBuffer类型的对象时不能用 StringBuffer sb = "abc"; 这是对于String类型可以使用的,从而储存在常量池中。
package day3;
public class stringtest1 {
public static void main(String[] args){
StringBuffer sb = new StringBuffer("abc");
sb.setCharAt(0, 'A');
System.out.println(sb);//Abc
String s = "abc";
String s1 = s.replace('a','A');
System.out.println(s);//abc
System.out.println(s1);//Abc
}
}
3. String和StringBuffer和StringBuilder区别的源码分析
- String str = new String(); 源码中:char[] str = new char[0];
- String str = new String("abc"); 源码中:char[] str = new char[]{'a','b','c'};
- String str = "abc"; 源码中:final char[] str = new char[]{'a','b','c'};
- StringBuffer str = new StringBuffer(); 源码中:char[] str = new char[16]; 创建了长度为16的char[]。如果容量不够用就扩容。
- StringBuffer str = new StringBuffer("abc"); 源码中:char[] str = new char[16+str.length()]; 创建了长度为19的char[]。相当于多扩容了16个位置。
- 对于StringBuffer的 str,虽然创建时都多扩容了16个位置,但是str.length()还是实际长度
- 对于StringBuffer str = new StringBuffer(); 这种构造方式,因为一开始默认创建16个容量的char[],再之后添加元素的时候如果超出容量,要重新创建一个长度等于原来容量的2倍 + 2的char[],再把原来的数组复制到新数组中。我们推荐利用StringBuffer str = new StringBuffer(int capacity); StringBuiler str = new StringBuiler(int capacity);这种构造方式,避免复制等操作。
- StringBuffer和StringBuilder在上面源码是一样的,都是可变的。
4. StringBuffer和StringBuiler的常用方法:(StringBuffer和StringBuiler的常用方法一样,只介绍StringBuffer)
注意void类型的方法都是直接对原字符串进行修改,有返回值的就是没修改原来的字符串,而是返回一个新的字符串
StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接 StringBuffer delete(int start,int end):删除指定位置的内容,左闭右开 StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str StringBuffer insert(int offset, xxx):在指定位置前插入xxx,xxx支持多种基本数据类型转化为string StringBuffer reverse() :把当前字符序列逆转 public int indexOf(String str) 返回str在原字符串中出现的位置 public String substring(int start,int end):返回一个从start开始到end索引结束的左闭右开区间的子字符串 public int length() public char charAt(int n ) public void setCharAt(int n ,char ch) 总结: 增:append(xxx) 删:delete(int start,int end) 改:setCharAt(int n ,char ch) / replace(int start, int end, String str) 查:charAt(int n ) 插:insert(int offset, xxx) 长度:length();
示例:对于StringBuffer s = new StringBuffer("hello");
- 自动将基本数据类型转成string后增加到最后。
- s1.append(1); //hello1
- s1.append('1');//hello1
- s1.append(false);//hellofalse
- s1.append(11.01);//hello11.01
- s1.delete(2,4); //heo 左闭右开
- s1.replace(2,4,"aa");// heaao
- s1.insert(1,1); // h1ello
- s1.reverse(); // olleh
5. String和StringBuffer和StringBuilder的效率
对比String、StringBuffer、StringBuilder三者的效率:“注意这里string是用字面量的方式创建” 从高到低排列:StringBuilder > StringBuffer > String
String最低的原因是不可变,所以每次操作都是需要重新在常量池里创建。