1.区别
(1). String : 不可变字符序列.
(2). StringBuffer : 可变字符序列.线程安全,但效率低.
(3). StringBuilder : 可变字符序列.线程不安全,但效率高.
既然StringBuffer与StringBuilder都是可变字符序列,但二者咋区分开呢?
查看源码 : 发现StringBuffer类中的方法都用了synchronized修饰,即其中的方法都是同步方法.故线程更安全.
查看源码 : StringBuilder类中的方法并没有用到synchronized修饰.线程不安全.但节省了握锁的时间,所以效率更高.
2.StringBuffer/StringBuilder可变性分析
(1). 针对于StringBuilder来说,有两个属性需要注意.其实你在该类的源码中是找不到这两个属性的,因为他们其实声明在其父类AbstractStringBuilder中.
(jdk8.0版本)char[] value : 存储字符序列.注意,String类中该数组是用final修饰的,而此处没有,侧面也可以体现出可变性序列.
int count : 实际存储字符的个数.
StringBuilder sBuilder1 =new StringBuilder(); //char[] value = new char[16]; sBuilder1.append("hex"); //value[0] = 'h'; //value[1] = 'e'; //value[2] = 'x';
(2).因为我用的是jdk17版本,所以源码value数组我byte[]类型.
StringBuilder sBuilder1 =new StringBuilder()底层
//构造器 public StringBuffer() { super(16); } //底层new了一个16个字节的字节数组 value = new byte[capacity];
StringBuilder sBuilder2 =new StringBuilder("abc")底层
public StringBuilder(String str) { super(str); } //截取了一部分源码 int length = str.length(); int capacity = (length < Integer.MAX_VALUE - 16) ? length + 16 : Integer.MAX_VALUE; coder = initCoder; value = (initCoder == LATIN1) ? new byte[capacity] : StringUTF16.newBytesFor(capacity);
很清晰看到 : byte[] value =new byte[16+str.length()];
append : 追加
如果append的字符串的长度<16,如下.
如果追加的字符串长度>16,先判断有没有length是否大于16*2+2;如果小于34,则分配char[] value =new char[34];如果大于,则分配char[] value =new char[str.length];
StringBuilder sBuilder1 =new StringBuilder() //char[] value = new char[16]; sBuilder1.append("hex"); //value[0] = 'h'; //value[1] = 'e'; //value[2] = 'x';
3.说明
- 如果开发中需要对字符串频繁的进行增删插的操作,就考虑使用StringBuffer/StringBuilder.
- 如果开发中不涉及到多线程问题,则考虑使用StringBuilder,因为它效率更高.
- 如果开发中大体确定字符串的长度,则可以考虑使用StringBuilder带参构造器,避免底层多次扩容操作.
4.StringBuilder/StringBuffer常见方法.
//字符串追加 public StringBuilder append(StringBuffer sb) //字符串删除[start, end) public StringBuilder delete(int start, int end) //删除字符串指定索引字符 public StringBuilder deleteCharAt(int index) //字符串替换 public StringBuilder replace(int start, int end, String str) //字符串插入 public StringBuilder insert(int offset, String str) //字符串反转 public StringBuilder reverse()