以下内容翻译自api
StringBuilder
可以改变字符的顺序。不能保证线程同步。StringBuilder可以作为单线程中StringBuffer的直接替换。如果有可能的话,推荐使用StringBuilder,因为多数情况下它比StringBuffer快很多。
StringBuilder的基本方法有append和insert,这两个方法通过重载可以传入多种类型的参数。他们都可以有效的将传入的参数转换成字符串,然后可以插入或者追加一个字符到String builder中。append方法总是在字符串的末尾追加数据,inert方法可以在指定位置插入字符。
一般来说,sb.append()和sb.insert(sb.length(), x)的效果是一样的。
每一个stringBuilder都是有容量的,只要字符串的长度没有超出stringBuilder容量,就没有必要为stringBuilder分配内部缓存,如果内部缓存溢出了,StringBuilder会自动扩容。
StringBuilder在多线程的下是不安全的,如果要求同步的话,推荐使用StringBuffer.
如果没有特殊说明,对构造函数和方法传入null对象时,将会抛出空指针异常。
StringBuilder的默认容量为16
public StringBuilder() {
super(16);
}
StringBuffer
线程安全的,可改变顺序的字符串;StringBuffer像是一个string但是内容是可以修改的,任何时候,StringBuffer包含一个字符串,都可以通过调用一定的方法修改它的长度和内容;
StringBuffer在多线程中可以安全的。它的一些方法是同步的,这样就可确保一个实例的所有操作将会按照线程内的方法调用顺序来执行。
StringBuffer的基本方法有append和insert(此部分的内容于stringBuilder是一样的);
从jdk1.5开始,stringBuffer作为单线程类stringBuilder的一个补充。StringBuilder优先于StringBuffer,因为它们提供相同的方法,stringBuilder比stringBuffer更快,但是StringBuilder不是同步的。
默认容量是16
public StringBuffer() {
super(16);
}
StringBuffer中的同步是使用synchronized关键字实现的。
例如
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
扩容使用的是AbstractStringBuilder类中的方法
/** * This implements the expansion semantics of ensureCapacity with no * size check or synchronization. */ void expandCapacity(int minimumCapacity) { int newCapacity = value.length * 2 + 2; if (newCapacity - minimumCapacity < 0) newCapacity = minimumCapacity; if (newCapacity < 0) { if (minimumCapacity < 0) // overflow throw new OutOfMemoryError(); newCapacity = Integer.MAX_VALUE; } value = Arrays.copyOf(value, newCapacity); }
面试题总结:
1 String s = new String("hello")和String s = "hello"的区别
第一个首先在堆中分配内存,将内存地址返回给栈中的s,然后去方法区中看是否有hello如果没有则在方法区中分配一个空间存放,并将地址返回给堆中的对象
第二个直接看方法区中是否有hello对象,并将地址返回给栈中的s,不经过创建对象的过程
2 字符串相加?
(1)字符串如果是变量相加,先开空间,再拼接;
(2)字符串如果是常量相加,先加,之后在变量池找,如果有就直接返回,没有,就创建。
3 string stringbuilder stringbuffer的区别
string是常量,不能修改
StringBuilder和StringBuffer可以修改
StringBuffer是线程安全的,因为使用了synchronized关键字,效率较差
StringBuilder是线程不安全的,但速度快