• StringBuffer 源码分析


    StringBuffer继承了AbstractStringBuilder,我们主要来看下AbstractStringBuilder这个类:
    
    AbstractStringBuilder
    
    1)、成员
    
    /**
    * The value is used for character storage.
    */
    char value[];
    
    /** 
    * The count is the number of characters used.
    */
    int count;
    
    2)、方法
    
    1、提供了两种构造器
    
    AbstractStringBuilder() {
    }
    
    
    AbstractStringBuilder(int capacity) {
    value = new char[capacity];
    }
    
    可以看出,第二种构造器可以在构造对象的时候就指定维护的数组的初始大小
    
    2、扩容
    
    public void ensureCapacity(int minimumCapacity) {
    if (minimumCapacity > value.length) {
    expandCapacity(minimumCapacity);
    }
    }
    
    void expandCapacity(int minimumCapacity) {
    int newCapacity = (value.length + 1) * 2;
    if (newCapacity < 0) {
    newCapacity = Integer.MAX_VALUE;
    } else if (minimumCapacity > newCapacity) {
    newCapacity = minimumCapacity;
    }
    value = Arrays.copyOf(value, newCapacity);
    }
    
    可以看出,如果维护的数组的长度不够,则会将长度变为原来的两倍
    
    3public void trimToSize() {
    if (count < value.length) {
    value = Arrays.copyOf(value, count);
    }
    }
    
    减少数组的长度到元素的个数
    
    4public void setLength(int newLength) {
    if (newLength < 0)
    throw new StringIndexOutOfBoundsException(newLength);
    if (newLength > value.length)
    expandCapacity(newLength);
    
    if (count < newLength) {
    for (; count < newLength; count++)
    value[count] = '';
    } else {
    count = newLength;
    }
    }
    
    设置sequence长度
    
    5、append方法
    
    public AbstractStringBuilder append(String str) {
    if (str == null) str = "null";
    int len = str.length();
    if (len == 0) return this;
    int newCount = count + len;
    if (newCount > value.length)
    expandCapacity(newCount);
    str.getChars(0, len, value, count);
    count = newCount;
    return this;
    }
    
    //本方法是StringBuffer append方法的核心,主要就是在扩容后,将append的字符串直接拷贝到扩容后的数组的相关位置上,并没有new其他不需要的对象
    
    public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
    if (srcBegin < 0) {
    throw new StringIndexOutOfBoundsException(srcBegin);
    }
    if (srcEnd > count) {
    throw new StringIndexOutOfBoundsException(srcEnd);
    }
    if (srcBegin > srcEnd) {
    throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
    }
    System.arraycopy(value, offset + srcBegin, dst, dstBegin,
    srcEnd - srcBegin);
    }
    
    这里与String拼接字符串的方式做一下比较:
    
    String在进行“+”拼接时,会new临时的StringBuffer对象,即  new StringBuilder().append(str).append("asjdkla").toString(),一旦在循环中做拼接字符串的操作,那么将会new大量StringBuffer和String(StringBuffer的toString方法会new String),导致开销极大
    
    下面我们再看下String的concat方法
    
    public String concat(String str) {
    int otherLen = str.length();
    if (otherLen == 0) {
    return this;
    }
    char buf[] = new char[count + otherLen];
    getChars(0, count, buf, 0);
    str.getChars(0, otherLen, buf, count);
    return new String(0, count + otherLen, buf);
    }
    
    很明显,这种方式比使用“+”的方式好一些,但是还是new了多余的String对象,一旦在循环中调用,还是对性能有很大影响的
    
     
  • 相关阅读:
    uva 10561 sg定理
    二进制下 求分数化小数的循环节问题
    zoj 2562 反素数
    uva 11916 解模方程a^x=b (mod n)
    Android 组件化方案探索与思考
    2018谷歌I/O开发者大会8大看点汇总 新品有哪些
    Glide高级详解—缓存与解码复用
    Android性能优化:手把手带你全面实现内存优化
    Android几种强大的下拉刷新库
    Android app 在线更新那点事儿(适配Android6.0、7.0、8.0)
  • 原文地址:https://www.cnblogs.com/lige-H/p/7406316.html
Copyright © 2020-2023  润新知