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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

ArrayList方法源码

發(fā)布時間:2024/2/28 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ArrayList方法源码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

三種構(gòu)造函數(shù)

不帶參數(shù)的構(gòu)造函數(shù)

public ArrayList() {// 如果沒有傳入初始容量,則使用空數(shù)組DEFAULTCAPACITY_EMPTY_ELEMENTDATA// 使用這個數(shù)組是在添加第一個元素的時候會擴容到默認大小10this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }

帶初始容量的構(gòu)造函數(shù)

public ArrayList(int initialCapacity) {if (initialCapacity > 0) {// 如果傳入的初始容量大于0,就新建一個數(shù)組存儲元素this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {// 如果傳入的初始容量等于0,使用空數(shù)組EMPTY_ELEMENTDATAthis.elementData = EMPTY_ELEMENTDATA;} else {// 如果傳入的初始容量小于0,拋出異常throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);} }

帶集合的構(gòu)造函數(shù)

/** * 把傳入集合的元素初始化到ArrayList中 */ public ArrayList(Collection<? extends E> c) {// 集合轉(zhuǎn)數(shù)組elementData = c.toArray();if ((size = elementData.length) != 0) {// 檢查c.toArray()返回的是不是Object[]類型,如果不是,重新拷貝成Object[].class類型if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);} else {// 如果c的空集合,則初始化為空數(shù)組EMPTY_ELEMENTDATAthis.elementData = EMPTY_ELEMENTDATA;} }

add(E e) 方法

public boolean add(E e) {// 檢查是否需要擴容ensureCapacityInternal(size + 1);// 把元素插入到最后一位elementData[size++] = e;return true; }private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }private static int calculateCapacity(Object[] elementData, int minCapacity) {// 如果是空數(shù)組DEFAULTCAPACITY_EMPTY_ELEMENTDATA,就初始化為默認大小10if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity; }private void ensureExplicitCapacity(int minCapacity) {modCount++;if (minCapacity - elementData.length > 0)// 擴容grow(minCapacity); }private void grow(int minCapacity) {int oldCapacity = elementData.length;// 新容量為舊容量的1.5倍int newCapacity = oldCapacity + (oldCapacity >> 1);// 如果新容量發(fā)現(xiàn)比需要的容量還小,則以需要的容量為準if (newCapacity - minCapacity < 0)newCapacity = minCapacity;// 如果新容量已經(jīng)超過最大容量了,則使用最大容量if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// 以新容量拷貝出來一個新數(shù)組elementData = Arrays.copyOf(elementData, newCapacity); }

添加一個元素的過程頗為復(fù)雜,那么大致來說就是,會有個檢查是否擴容的方法。?

首先判斷elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA,直接返回最小容量值 10 .

如果不是的話 那么就返回minCapacity。

minCapacity可以這么理解 要求最小的容量。

接下來又有一個判斷?if (minCapacity - elementData.length > 0)? 對這句話的理解為要求最小的容量比存儲數(shù)據(jù)的數(shù)組長度大的話,那么說明需要擴容了,就得執(zhí)行g(shù)row()方法了。

add(int index, E element)方法

public void add(int index, E element) {// 檢查是否越界rangeCheckForAdd(index);// 檢查是否需要擴容ensureCapacityInternal(size + 1);// 將inex及其之后的元素往后挪一位,則index位置處就空出來了System.arraycopy(elementData, index, elementData, index + 1,size - index);// 將元素插入到index的位置elementData[index] = element;// 大小增1size++; }private void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }

addAll 方法

/** * 將集合c中所有元素添加到當前ArrayList中 */ public boolean addAll(Collection<? extends E> c) {// 將集合c轉(zhuǎn)為數(shù)組Object[] a = c.toArray();int numNew = a.length;// 檢查是否需要擴容ensureCapacityInternal(size + numNew);// 將c中元素全部拷貝到數(shù)組的最后System.arraycopy(a, 0, elementData, size, numNew);// 大小增加c的大小size += numNew;// 如果c不為空就返回true,否則返回falsereturn numNew != 0; }

?get(int index)方法

public E get(int index) {// 檢查是否越界rangeCheck(index);// 返回數(shù)組index位置的元素return elementData(index); }private void rangeCheck(int index) {if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }E elementData(int index) {return (E) elementData[index]; }

remove(int index)方法?

public E remove(int index) {// 檢查是否越界rangeCheck(index);modCount++;// 獲取index位置的元素E oldValue = elementData(index);// 如果index不是最后一位,則將index之后的元素往前挪一位int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index, numMoved);// 將最后一個元素刪除,幫助GCelementData[--size] = null; // clear to let GC do its work// 返回舊值return oldValue; }

numMoved代表著需要前移多少個元素,如果等于0的話,那么此時的index=size-1? ?就是要刪除最后一個元素,所以直接將最后一個元素設(shè)為null即可。

remove(Object o)方法?

public boolean remove(Object o) {if (o == null) {// 遍歷整個數(shù)組,找到元素第一次出現(xiàn)的位置,并將其快速刪除for (int index = 0; index < size; index++)// 如果要刪除的元素為null,則以null進行比較,使用==if (elementData[index] == null) {fastRemove(index);return true;}} else {// 遍歷整個數(shù)組,找到元素第一次出現(xiàn)的位置,并將其快速刪除for (int index = 0; index < size; index++)// 如果要刪除的元素不為null,則進行比較,使用equals()方法if (o.equals(elementData[index])) {fastRemove(index);return true;}}return false; }private void fastRemove(int index) {// 少了一個越界的檢查modCount++;// 如果index不是最后一位,則將index之后的元素往前挪一位int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index, numMoved);// 將最后一個元素刪除,幫助GCelementData[--size] = null; // clear to let GC do its work }

總結(jié)

(1)ArrayList內(nèi)部使用數(shù)組存儲元素,當數(shù)組長度不夠時進行擴容,每次加一半的空間,ArrayList不會進行縮容;

(2)ArrayList支持隨機訪問,通過索引訪問元素極快,時間復(fù)雜度為O(1);

(3)ArrayList添加元素到尾部極快,平均時間復(fù)雜度為O(1);

(4)ArrayList添加元素到中間比較慢,因為要搬移元素,平均時間復(fù)雜度為O(n);

(5)ArrayList從尾部刪除元素極快,時間復(fù)雜度為O(1);

(6)ArrayList從中間刪除元素比較慢,因為要搬移元素,平均時間復(fù)雜度為O(n);

(7)ArrayList支持求并集,調(diào)用addAll(Collection<? extends E> c)方法即可;

(8)ArrayList支持求交集,調(diào)用retainAll(Collection<? extends E> c)方法即可;

(7)ArrayList支持求單向差集,調(diào)用removeAll(Collection<? extends E> c)方法即可;

?

總結(jié)

以上是生活随笔為你收集整理的ArrayList方法源码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。