我正在尝试编写一个方法,该方法有效地包装传递给此方法的List
中的每个元素,并返回带有包装元素的创建ArrayList
。
根据文档:
size((、isEmpty((、get((、set((、iterator(( 和 listIterator(( 操作在常量时间内运行。添加操作在摊销常量时间内运行,即添加 n 个元素需要 O(n( 时间。所有其他操作都以线性时间运行(粗略地说(。与 LinkedList 实现相比,常量因子较低。
我是否正确理解,如果我创建一个ArrayList
并将初始容量传递给构造函数,则添加新元素时ArrayList
中的元素不会在内存中重新分配?
例:
public static <T> ArrayList<RequestToExternalSource<T>> wrapExternalSources(List<ExternalSource<T>> externalSources, BiConsumer<Integer, T> publishResult) {
ArrayList<RequestToExternalSource<T>> requests = new ArrayList<>(externalSources.size());
ListIterator<ExternalSource<T>> externalSourcesIterator = externalSources.listIterator();
int index = 0;
while (externalSourcesIterator.hasNext()) {
requests.add(new RequestToExternalSource<>(
index++,
externalSourcesIterator.next(),
publishResult));
}
return requests;
}
要回答这个问题,我们可以直接查看ArrayList#add
的源代码。 我们首先看到以下方法:
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
上面的方法调用以下private
、重载add
方法:
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
我们可以看到,只有当s
(大小参数,在我们的例子中等于ArrayList#size
(等于数据数组的长度时,elementData
(保存数据的Object[]
(才会增长。 出于这个原因,即使我们将n
元素添加到以 n
容量初始化的ArrayList
中,elementData
也不会增长,这很好!
我是否正确理解,如果我创建一个 ArrayList 并将初始容量传递给构造函数,则添加新元素时,ArrayList 中的元素不会在内存中重新分配?
由于这些原因,是的,您是对的,直到您添加的元素超过指定的容量。