一、String、StringBuffer和StringBuilder的主要区别
String | 字符串常量(线程安全) | 中等 |
StringBuffer | 字符串变量(线程安全) | 慢 |
StringBuilder | 字符串变量(线程不安全) | 快 |
二、String、StringBuffer和StringBuilder的源码
String源码
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
其中String 是final类的char数组,是不可改变的,也正如《Java编辑思想》 所说"String对象是不可改变的"
StringBuilder 和StringBuffer的源码
- StringBuffer是单线程的,因为里面的方法都是被synchronized修饰了。所以它线程安全,但是效率自然就降低。
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
- StringBuilder不是是单线程的,因为里面的方法没有被synchronized修饰了。所以它线程不安全,所以效率要更高。
public StringBuilder append(StringBuffer sb) {
super.append(sb);
return this;
}
然而StringBuilder适用绝大部分的场合,而StringBuffer的线程安全,仅仅保障jvm不爬出异常而顺利下去,不可以保障逻辑正确和调用顺序。大部分情况下需要不仅仅是线程安全,而是锁。
三、StringBuilder的一些常用方法
/*String 长度大小不可变
StringBuffer 和 StringBuilder 长度可变
StringBuffer 线程安全 StringBuilder 线程不安全
StringBuilder 速度快*/
public class StringBuilderTest {
//append() 增加
@Test
public void appendTest() {
StringBuilder sb = new StringBuilder(); //新增一个对象
sb.append("abc").append(true).append(123);
System.out.println(sb);
System.out.println("--------------");
//判断sb与sb1是否相等
StringBuilder sb1 = sb.append(1);
System.out.println("sb == sb1:" + (sb==sb1));
System.out.println("sb equals sb1"+sb.equals(sb1));
StringBuilder sb2 = new StringBuilder();
sb2.append("abc").append(true).append(123).append(1);
System.out.println("sb == sb2" + (sb==sb2));
System.out.println(sb.toString());
System.out.println(sb1.toString());
System.out.println(sb2.toString());
System.out.println("----------------");
//insert() 指定位置插入
sb.insert(2, "Java"); //在第二位后(abctrue1231中的'b'后添加Java)
System.out.println(sb.toString());
//delete()删除缓冲区的数据 包含start,不包含end [ )
sb.delete(3, 5); //[3,5) 删掉3和4
System.out.println(sb.toString());
sb.deleteCharAt(1); //删除指定位置的数据
System.out.println(sb.toString());
//sb.delete(0,sb.length()):清空缓冲区
System.out.println("----------------");
//获取
/*char charAt(int index)
返回此序列中指定索引处的 char 值*/
/*int indexOf(String str)
返回第一次出现的指定子字符串在该字符串中的索引*/
/*int lastIndexOf(String str, int fromIndex)
返回 String 对象中子字符串最后出现的位置*/
System.out.println(sb.charAt(2));
System.out.println(sb.indexOf("1"));
System.out.println("----------------");
//修改(替换)
/*replace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符*/
/* setCharAt(int index, char ch)
给String中的指定数据替换 用到是单引号''*/
sb.replace(6, 7, "hi");
sb.setCharAt(1, 'L');
System.out.println(sb.toString());
}
}
四、结尾
String、StringBuffer和StringBuilder的区别在面试过程中是很容易被问道的一个基础题,已上也是通过浏览别人的博客和api总结的一些要点,方便去理解。