日期:2014-05-20  浏览次数:20705 次

StringBuffer.capacity()返回的是什么?

public class TestStringBuilder {

public static void main(String[] args) {
// TODO Auto-generated method stub
StringBuilder string = new StringBuilder();
char[] array = new char[]{'1','2','3'};
System.out.println(string.capacity());
System.out.println(string.append(array));
System.out.println(string.append("daiwei"));
System.out.println(string.insert(3, "Hello"));
System.out.println(string.replace(4, 7, "fff")); //4~6 = fff
System.out.println(string.toString());
System.out.println(string.length());
System.out.println(string.capacity());
string.setLength(17);
System.out.println(string.length());
System.out.println(string.capacity());//为什么这里是34?

System.out.println(string.toString());
}

}

------解决方案--------------------
是该Builder/Buffer目前的缓存总量。这个量是Buffer/Builder类自主管理的,在构造函数中可以制定初始量,如:
StringBuilder sb = new StringBuilder(200);
System.out.println(sb.capacity()); // 200

优化方案:当你知道你的String大约是多大的时候,就用构造函数直接分配出那么多,否则默认长度是16,而你建立的String个个都是300,那将会经历多次扩容,而扩容是个相对昂贵的操作
------解决方案--------------------
StringBuffer buf = new StringBuffer(); 
这句话表示初始化了一个空的初始容量为16个字符的空间大小。 
所以一开始string.capacity()都是16

AbstractStringBuilder里的expandCapacity(int minimumCapacity)完成数组扩容,源码如下: 
 
void expandCapacity(int minimumCapacity) {  
int newCapacity = (value.length + 1) * 2; //先以(当前容量+1)*2扩容  
       if (newCapacity < 0) {  
           newCapacity = Integer.MAX_VALUE;  
       } else if (minimumCapacity > newCapacity) {  //如果增长超过上面扩容的容量,以增长的容量进行扩容  
    newCapacity = minimumCapacity;  
}  
       value = Arrays.copyOf(value, newCapacity);  
   }
  
所以setlength=17的时候,会以原来容量(16+1)*2=34进行扩容。
你可以自己试试setlength=35验证一下