我理解容量是ArrayList中元素或可用空间的数量,这些元素或可用空间可能包含也可能不包含引用对象的值。我正在尝试更多地了解容量的概念。
所以我有三个问题:
1)从内存的角度来看,定义容量的一些好方法是什么?
...the (连续?)分配给ArrayList的内存?
...the数组列表的内存占用(堆?)?
2)那么,如果上述情况属实,那么改变容量需要某种形式的内存管理开销?
3)谁有一个#2曾经或可能成为性能问题的例子?除了可能有大量的大型ArrayLists不断调整它们的容量之外?
发布于 2011-03-24 04:31:03
,
发布于 2011-03-24 04:30:34
ArrayList的实现方式如下:
class ArrayList {
private Object[] elements;
}
容量是该数组的大小。
现在,如果您的容量是10,并且您要添加第11个元素,ArrayList将执行以下操作:
Object[] newElements = new Object[capacity * 1.5];
System.arraycopy(this.elements, newElements);
this.elements = newElements;
所以如果你一开始只有很小的容量,当你不断添加元素时,ArrayList最终会创建一堆数组,并为你复制东西,这是不好的。
另一方面,如果您指定的容量为1,000,000,并且只向ArrayList添加3个元素,这也是一种糟糕的情况。
经验法则:如果您知道容量,请指定它。如果您不确定但知道上限,请指定它。如果你只是不确定,使用默认值。
发布于 2011-03-24 04:33:29
容量正如您所描述的那样--分配给ArrayList用于存储值的连续内存。ArrayList将所有值存储在数组中,并自动调整数组的大小。这会在调整大小时产生内存管理开销。
如果我没记错的话,当您尝试添加一个超出容量的元素时,Java会将ArrayList的后备数组的大小从N增加到2N +2。我不知道当您使用insert
方法(或类似方法)在超出容量的特定位置插入时,它会增加到什么大小,甚至不知道它是否允许这样做。
这里有一个例子来帮助你思考它是如何工作的。将|
之间的每个空格想象为支持数组中的一个单元:
| | |
size =0(不包含元素),capacity =2(可以包含2个元素)。
|1| |
大小=1(包含1个元素),容量=2(可以包含2个元素)。
|1|2|
大小= 2,容量= 2。添加另一个元素:
|1|2|3| | | |
大小增加了1,容量增加到6 (2 *2+ 2)。对于大型数组,这可能很昂贵,因为分配大型连续内存区域可能需要一些工作(与分配许多小内存的LinkedList相反),因为JVM需要搜索适当的位置,并且可能需要向OS请求更多内存。将大量值从一个位置复制到另一个位置的成本也很高,一旦找到这样的区域,就会执行此操作。
我的经验法则是:如果您知道所需的容量,请使用ArrayList,因为只有一次分配,而且访问速度非常快。如果您不知道所需的容量,请使用LinkedList,因为添加新值始终需要相同的工作量,并且不涉及复制。
https://stackoverflow.com/questions/5411095
复制相似问题