JAVA里,ArrayList在内存分配上究竟是怎样的?

我猜的:
ArrayList:
初始化的时候不指定元素个数:在不同的时刻对其增删插,元素在内存中不可能连续(中间的内存会被其他对象占掉);

初始化的时候指定元素个数:可以暂时连续存储,但后期如果在不同的时刻对其增删插,元素也不可能连续。

因此,在索引ArrayList时,速度往往会比数组慢(但我猜这背后肯定会有一些优化机制,当然这种慢在需要ArrayList的时候是可以原谅的)。
另外,ArrayList的内存模型是什么?有人说是队列,但队列是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表,貌似不对吧?

ArrayList就是动态数组,也是一个对象。

创建一个ArrayList对象,该对象存放在堆内存中,且是一个内存连续的内存区域。

1、ArrayList是用数组实现的,这个数组的内存是连续的,不存在相邻元素之间还隔着其他内存。

2、索引ArrayList时,速度比原生数组慢是因为你要用get方法,这是一个函数调用,而数组直接用[ ]访问,相当于直接操作内存地址,速度当然比函数调用快。

3、新建ArrayList的时候,JVM为其分配一个默认或指定大小的连续内存区域(封装为数组)。

4、每次增加元素会检查容量,不足则创建新的连续内存区域(大小等于初始大小+步长),也用数组形式封装,并将原来的内存区域数据复制到新的内存区域,然后再用ArrayList中引用原来封装的数组对象的引用变量引用到新的数组对象:

elementData = Arrays.copyOf(elementData, newCapacity);

5、集合内存分配以及初始化过程图解

温馨提示:答案为网友推荐,仅供参考
第1个回答  2018-07-05
ArrayList就是动态数组,也是一个对象。
创建一个ArrayList对象,该对象存放在堆内存中,且是一个内存连续的内存区域。
1、ArrayList是用数组实现的,这个数组的内存是连续的,不存在相邻元素之间还隔着其他内存。
2、索引ArrayList时,速度比原生数组慢是因为你要用get方法,这是一个函数调用,而数组直接用[ ]访问,相当于直接操作内存地址,速度当然比函数调用快。
3、新建ArrayList的时候,JVM为其分配一个默认或指定大小的连续内存区域(封装为数组)。
4、每次增加元素会检查容量,不足则创建新的连续内存区域(大小等于初始大小+步长),也用数组形式封装,并将原来的内存区域数据复制到新的内存区域,然后再用ArrayList中引用原来封装的数组对象的引用变量引用到新的数组对象:
elementData = Arrays.copyOf(elementData, newCapacity);
第2个回答  2014-07-19
打开源代码,ArrayList的底层很清楚,就是数组。

当add()容量够时,就是直接在后面添加,速度很快。
当add()容量不够时,就将新建一个更大的数组,然后把旧数组的内容复制过去。
当在中间位置插入时,会把插入点及后面的数据后移一个位置。然后插入。
当在中间位置删除时,会将删除点后面的数据前移一个位置。

所以说任何时间点,其内存都是连续的,随机索引访问效率很高。
插入,删除效率低。或者容量满时add()效率低。

新建一个ArrayList可以指定初始容量,也可以不指定初始容量。
-----------------
还有一种LinkdedList,他的底层是基于链表的。
特点是
遍历较快,但随机访问比较慢list.get()。添加、删除比较快。本回答被提问者和网友采纳
相似回答