日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

学习笔记——ArrayList总结

發布時間:2025/5/22 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学习笔记——ArrayList总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ArrayList可以說是一種很常用很常用的數據結構了。

ArrayList底層是通過數組實現的。可以看下源碼(基于JDK1.8)

首先從構造函數說起,總共有三種構造函數:

public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {this.elementData = EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);}}public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}public ArrayList(Collection<? extends E> c) {elementData = c.toArray();if ((size = elementData.length) != 0) {// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);} else {// replace with empty array.this.elementData = EMPTY_ELEMENTDATA;}} View Code

其中最常用的就是無參構造函數。

private static final int DEFAULT_CAPACITY = 10;

private
static final Object[] EMPTY_ELEMENTDATA = {};private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

無參構造函數創建的是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,這里之所以要區分出EMPTY_ELEMENTDATA,主要是因為當DEFAULTCAPACITY_EMPTY_ELEMENTDATA擴容時,

會優先按默認大小(DEFAULT_CAPACITY)進行擴容。具體可以看這個方法:

private void ensureCapacityInternal(int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);}ensureExplicitCapacity(minCapacity);}

這樣就將原本初始化時就要做的內存分配推遲到了真正使用時,算是一點優化吧。

?

ArrayList的存儲

transient Object[] elementData;

在ArrayList中elementData是實際用來存放數據的數組。

默認大小是10,當數組滿后,按1.5倍進行擴容。

代碼如下:

private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);} View Code

但這樣很容易造成內存的浪費,特別是當ArrayList比較大的時候,比如當前數組大小是20000,已填滿,當再添加一個新元素時,就需要擴容成30000。但實際真實只使用了20001,9999就是浪費的。

對此ArrayList提供了trimToSize方法。此外,ArrayList之所以將elementData定義成transient,自己實現序列化和反序列化的方法也是為了序列化的時候,只序列化數組中實際使用的部分。減少了序列化的時間,和序列化后的文件大小。

?

可變長

其實數組壓根就是不可變的,初始化長度是多少就是多少,ArrayList之所以可變長,都是通過創建一個新數組,將原數組的數據復制過去實現的。這是有性能開銷的。ArrayList中的remove,指定位置add方法,甚至trimToSize等很多方法都是依靠這個數組復制的方式實現的。需要注意,當可以預估到需要ArrayList中元素比較多的時候,最好是在初始化的時候直接指定ArrayList的大小。否則會導致頻繁的擴容,影響性能。

?

隨機訪問

ArrayList實現了RandomAccess接口。這是個標記接口。說明當前這個實現類是支持快速隨機訪問的。接口說明中給出了一個例子,按索引循環會比使用迭代器更快。

?

和Vector區別

?vector可以看成是線程安全的ArrayList,內部代碼實現大部分都是一樣的,只不過vector的方法都加上了synchronized鎖來保證線程安全。

此外vector默認按2倍擴容,也支持初始化的時候自定義每次擴容的大小。

源碼如下:

private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);elementData = Arrays.copyOf(elementData, newCapacity);} View Code

其中capacityIncrement就是自定義的擴容大小。

轉載于:https://www.cnblogs.com/boogieman/p/10150935.html

總結

以上是生活随笔為你收集整理的学习笔记——ArrayList总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。