关于java100个优化代码的信息( 二 )


StringBuffer (int size); //分配size个字符的空间
StringBuffer (String str); //分配16个字符+str.length()个字符空间
你可以通过StringBuffer的构造函数来设定它的初始化容量,这样可以明显地提升性能 。
这里提到的构造函数是StringBuffer(int length) , length参数表示当前的StringBuffer能保持的字符数量 。你也可以使用ensureCapacity(int minimumcapacity)方法在StringBuffer对象创建之后设置它的容量 。首先我们看看StringBuffer的缺省行为,然后再找出一条更好的提升性能的途径 。
StringBuffer在内部维护一个字符数组,当你使用缺省的构造函数来创建StringBuffer对象的时候,因为没有设置初始化字符长度,StringBuffer的容量被初始化为16个字符,也就是说缺省容量就是16个字符 。当StringBuffer达到最大容量的时候,它会将自身容量增加到当前的2倍再加2,也就是(2*旧值+2) 。如果你使用缺省值,初始化之后接着往里面追加字符,在你追加到第16个字符的时候它会将容量增加到34(2*16+2),当追加到34个字符的时候就会将容量增加到70(2*34+2) 。无论何事只要StringBuffer到达它的最大容量它就不得不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍――这也太昂贵了点 。所以总是给StringBuffer设置一个合理的初始化容量值是错不了的,这样会带来立竿见影的性能增益 。StringBuffer初始化过程的调整的作用由此可见一斑 。所以,使用一个合适的容量值来初始化StringBuffer永远都是一个最佳的建议 。
14、合理的使用Java类 java.util.Vector 。
简单地说,一个Vector就是一个java.lang.Object实例的数组 。Vector与数组相似,它的元素可以通过整数形式的索引访问 。但是,Vector类型的对象在创建之后,对象的大小能够根据元素的增加或者删除而扩展、缩小 。请考虑下面这个向Vector加入元素的例子:
Object bj = new Object();
Vector v = new Vector(100000);
for(int I=0;
I100000; I++) { v.add(0,obj); }
除非有绝对充足的理由要求每次都把新元素插入到Vector的前面,否则上面的代码对性能不利 。在默认构造函数中,Vector的初始存储能力是10个元素,如果新元素加入时存储能力不足 , 则以后存储能力每次加倍 。Vector类就对象StringBuffer类一样,每次扩展存储能力时,所有现有的元素都要复制到新的存储空间之中 。下面的代码片段要比前面的例子快几个数量级:
Object bj = new Object();
Vector v = new Vector(100000);
for(int I=0; I100000; I++) { v.add(obj); }
同样的规则也适用于Vector类的remove()方法 。由于Vector中各个元素之间不能含有“空隙” , 删除除最后一个元素之外的任意其他元素都导致被删除元素之后的元素向前移动 。也就是说,从Vector删除最后一个元素要比删除第一个元素“开销”低好几倍 。
假设要从前面的Vector删除所有元素 , 我们可以使用这种代码:
for(int I=0; I100000; I++)
{
v.remove(0);
}
但是,与下面的代码相比,前面的代码要慢几个数量级:
for(int I=0; I100000; I++)
{
v.remove(v.size()-1);
}
从Vector类型的对象v删除所有元素的最好方法是:
v.removeAllElements();
假设Vector类型的对象v包含字符串“Hello” 。考虑下面的代码,它要从这个Vector中删除“Hello”字符串:
String s = "Hello";
int i = v.indexOf(s);
if(I != -1) v.remove(s);
这些代码看起来没什么错误,但它同样对性能不利 。在这段代码中,indexOf()方法对v进行顺序搜索寻找字符串“Hello” , remove(s)方法也要进行同样的顺序搜索 。改进之后的版本是:

推荐阅读