ArrayList 的空间浪费主要体现在在list列表的结尾预留一定的容量空间,为什么要预留一定的容量空间呢?大神指教!
因为每次添加一次数据,就分配一次内存,如果不够分配了,需要开辟一块新的内存,整体复制现有数据,这件事想想都觉得费劲,我们既要考虑空间优化,也要考虑时间优化。
通过ArrayList扩容源码得知,当列表长度超过数组长度,开始调用 grow() 方法扩容,如果成功扩容1.5倍,就会在列表结尾处留出一定空间,ArrayList扩容不是楼上所说的机制。
/**
* This method controls the growth of ArrayList capacities. It represents
* a time-space tradeoff: we don't want to grow lists too frequently
* (which wastes time and fragments storage), but we don't want to waste
* too much space in unused excess capacity.
*
* NOTE: This method is inlined into {@link #add(Object)} for performance.
* If you change the method, change it there too!
*/
private static int newCapacity(int currentCapacity) {
int increment = (currentCapacity < (MIN_CAPACITY_INCREMENT / 2) ?
MIN_CAPACITY_INCREMENT : currentCapacity >> 1);
return currentCapacity + increment;
}
//上面是android源码Arraylist中的一个方法,大概的意思就是不想频繁修改底层数组的长度,又不想浪费太多的内存
//每次当前容量超过最小值的一半时,直接增加一倍的内存,这应该是google通过什么算法或者机制来确定的吧
有个叫最优运行还是最有内存什么鬼的东东, 就是集合这个东西, 一般在长度占用75%的时候就会扩容,说这样会让集合的某些相关IO速度或者其他什么鬼很好, 比如Map刚创建实例时 集合默认长度为16 占用了12个长度也就是加入12个键值对后,map就要扩容为32长度了以此内推。
所以如果你的集合要存大量数据, 最好一开始就给一个很长的长度。··