您的位置:首页 > 产品设计 > UI/UE

String/StringBuilder/StringBuffer

2017-03-15 20:54 381 查看
String
    JAVA中有字符串公共池,如果两个字符串具有相同的内容,它们将共享公共池内同一存储器。这样做是为了节省对经常使用的字符串存储。另一方面,通过new操作符和构造器创建的String对象,都存储在堆中,即是两个String的内容相同,它们也是相互独立的,没有共用存储。用equal()方法比较两个字符串的内容,用==比较两个变量的引用。
     String中使用字符数组(char[ ])来保存字符串:

/** The value is used for character storage. */
    private final char value[];

     由源码可知char之前有final修饰,String对象是不可变的。

StringBuilder
     StringBuilder继承了AbstractStringBuilder类。也是使用char数组保存字符串

/**
     * The value is used for character storage.
     */
    char[] value;

     
     但是它的对象是可变的,当StringBuilder对象进行append操作时,会调用父类的append方法。其中再调用ensureCapacityInternal(int)方法,确保value的容量能满足append后的长度,ensureCapacityInternal(int)方法中,若append后的长度大于当前value的length,则调用expandCapacity(int)方法进行扩容。expandCapacity(int)方法扩容规模为当前长度*2+2。使用Array.copyOf()方法,指定需要复制的数组和新的数组长度,返回一个新的字符数组对象。然后回到append()方法中,把要添加的字符串复制到扩容后的value中。源码如下:
[align=left]
[/align]

public AbstractStringBuilder append(StringBuffer sb) {
        if (sb == null)
            return appendNull();
        int len = sb.length();
        ensureCapacityInternal(count + len);
        sb.getChars(0, len, value, count);
        count += len;
        return this;
}

private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);
}

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);
}

StringBuffer
     StringBuffer与StringBuilder都继承了同一个父类AbstractStringBuilder。与StringBuilder不同的是,StringBuffer对方法或调用的方法加了同步锁(synchronized),因此StringBuffer是线程安全的。而StringBuilder是线程不安全的。

使用场景
     1、如果操作少量的数据,使用String
        2、单线程操作字符串缓冲区且有大量数据,使用StringBuilder。
        3、多线程操作字符串缓冲区且有大量数据,使用StringBuffer。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: