字符串就是一连串的字符序列。在JDK1.5之前,java提供String和StringBuffer两个类封装字符串,在JDK1.5又增加了StringBuilder类来封装字符串。
字符串操作几乎是所有笔试面试题的并不可少,带着一下的疑问去学习三者差别:
String
、StringBuffer
和StringBuilder
的区别- 为什么JDK1.5增加
StringBuilder
类 - 三者的应用场景
- 三者的性能效率比较
String、StringBuffer和StringBuilder的区别
- String类是不可变类,String对象一旦被创造以后,包含在这个对象中的字符序列是不可改变的,直到这个对象被销毁。
- StringBuffer和StringBuilder类型的字符串是可变的,StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变字符串对象的字符序列;StringBuilder提供的append()、insert()、reverse()、setLength()等方法可以改变字符串对象的字符序列。
- String类封装的是不可变数组。StringBuffer和StringBuilder封装的就是可变数组
- StringBuffer和StringBuilder基本相似,两者的构造器与方法基本相同。StringBuffer是线程安全的,所以多线程环境下效率相对较低,StringBuilder是非线程安全的,所以性能略高。(如果需要创建一个内存可变的字符串对象,则应该优先考虑使用StringBuilder类)
- String、StringBuffer和StringBuffer都实现了CharSequence接口,所以CharSequence可认为是一个字符串的协议接口。
从源码角度讨论内部实现方式
String
类关键源码分析:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[]; //表示了String底层是不可变数组
由此代码可以发现final解释了为什么String
是不可变的
2. StringBuffer
和StringBuilder
类的关键源码分析
StringBuffer
和StringBuilder
类都继承了AbstractStringBuilder
抽象类,
//AbstractStringBuilder 类关键代码片段
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value; //可以看出StringBuffer和StringBuilder底层是可变数组
由StringBuffer
和StringBuilder
的父类可以知道StringBuffer
和StringBuilder是可变的
StringBuffer
和StringBuilder
的初始化
public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
/** * Constructs a string buffer with no characters in it and an * initial capacity of 16 characters. */
public StringBuffer() { super(16);} //StringBuffer的初始值
/** * Constructs a string buffer with no characters in it and
* the specified initial capacity.
* * @param capacity the initial capacity.
* @exception NegativeArraySizeException if the {@code capacity}
* argument is less than {@code 0}.
*/
public StringBuffer(int capacity) { super(capacity);} //自定义创建容量
/** * Constructs a string buffer initialized to the contents of the * specified string. The initial capacity of the string buffer is
* {@code 16} plus the length of the string argument.
* * @param str the initial contents of the buffer.
*/
public StringBuffer(String str) { super(str.length() + 16); //StringBuffer的扩容
append(str);}
可以发现StringBuffer
的初始化容量是大小是16的char型数组,可以自定义大小,进行增加16的char型数组的扩容。StringBuilder
的构造函数实现方式相同。
StringBuffer
和StringBuilder
类方法的关键源码
//StringBuffer的方法
@Override
public synchronized int length() { return count;}
@Override
public synchronized int capacity() { return value.length;}
@Override
public synchronized void ensureCapacity(int minimumCapacity) { super.ensureCapacity(minimumCapacity);}
//StringBuilder的方法
@Override
public int indexOf(String str) { return super.indexOf(str);}
@Override
public int indexOf(String str, int fromIndex) { return super.indexOf(str, fromIndex);}
@Override
public int lastIndexOf(String str) { return super.lastIndexOf(str);}
可以发现StringBuffer
的方法有Synchronize,表示StringBuffer
是线程安全的,而StringBuilder
不是线程安全的。