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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

ArrayList底层实现原理「建议收藏」

發布時間:2023/12/15 综合教程 30 生活家
生活随笔 收集整理的這篇文章主要介紹了 ArrayList底层实现原理「建议收藏」 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ArrayList簡介
ArrayList是我們開發中非常常用的數據存儲容器之一,其底層是數組實現的,我們可以在集合中存儲任意類型的數據,ArrayList是線程不安全的,非常適合用于對元素進行查找,效率非常高。

源碼分析

創建了一個大小為0的數組,在后面會用到。

聲明了一個數組。

ArrayList的無參構造方法,將前面聲明創建的大小為0的數組賦給elementData數組。

這是ArrayList的有參構造方法,傳入一個int類型的變量,相當于我們在使用arrayList的時候指定list的大小。

如果傳入的參數大于0,則新建一個initialCapacity大小的數組。

傳入值等于0的話,將這個空數組給elementData。

下面我們來看add()方法的源碼:

使用到了一個size的參數,先看ensureCapacityInternal方法。

size參數在前面進行了聲明,作用是標識該數組的大小的。

先執行了calculateCapacity方法,將數組和原先數組大小+1的數值傳入。

對數組進行判斷,判斷該數組是否為空,
,這是一個空的數組,在前面聲明過,如果現存的數組等于空的,我們就返回一個數值,
,第一個變量是常量10,第二個是我們前面傳入進來的,比較它倆的大小,返回大的數值。

如果不為空的話,我么直接返回前面方法傳入的數值。進入ensureExplicitCapacity()方法。

modCount是前面聲明的變量,初始值為0。

首先進行判斷,如果新長度減去數組原先的長度大于0,我們則調用grow方法,并將新長度傳入進去。

這里就是ArrayList底層數組擴容的核心代碼。

新長度是舊長度加上舊長度的0.5,所以ArrayList底層數組每次擴容的大小都是1.5倍。

第一個if,如果新創建的長度小于傳入的數組長度,那么就更新newCapacity的值為minCapacity。

第二個if,如果新數組長度減去最大的數組長度大于0的話,會進入hugeCapacity再次進行判斷,返回Integer的最大長度,或者Integer的最大長度-8的長度。

之后完成數組復制,至此,ArrayList的底層擴容已經實現。

添加的方法說完了,下面我們來看看刪除的方法。

刪除是每次進行數組復制,然后讓舊的elementData置為null進行垃圾回收,代碼很簡單,一看就懂,但是我們可以從源碼中去發現使用技巧。

查詢的方法就更簡單了,直接返回查詢的對應數組中的值。

下面我們來自己寫一個簡易的ArrayListDemo。

/** * 作者:LKP * 時間:2018/7/13 */
public class ArrayListDemo { 

private Object[] arry;     //數組
private int size = 0;      //下標
public ArrayListDemo(){ 

this.arry = new Object[10];
}
public ArrayListDemo(int size) throws Exception { 

if(size > 0)
this.arry = new Object[size];
else
throw new Exception("長度不允許小于零!");
}
//新增
public void add(Object number){ 

if(size >= arry.length){ 

int length = arry.length;
Object[] newArry = new Object[length];
for(int i=0; i<arry.length; i++){ 

newArry[i] = arry[i];
}
length = (length*3)/2+1;        //更新數組長度
arry = new Object[length];      //對原有數組進行擴容
for(int j=0; j<newArry.length; j++){ 

arry[j] = newArry[j];
}
newArry = null;     //釋放該數組
}
arry[size] = number;
size++;
}
//讀取
public Object get(int index) throws Exception { 

if(index >= 0)
return arry[index];
throw new Exception("下標不符合要求!");
}
//獲得大小
public int getSize(){ 

int count = 0;
for(int i=0; i<arry.length; i++){ 

if(arry[i] != null){ 

count++;
}
}
return count;
}
}

客戶端代碼:

/** * 作者:LKP * 時間:2018/7/13 */
public class demo { 

public static void main(String[] args){ 

ArrayList ls = new ArrayList();
ArrayListDemo list = new ArrayListDemo();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
for(int i=0; i<list.getSize(); i++) { 

try { 

System.out.println("List的值:"+list.get(i));
} catch (Exception e) { 

e.printStackTrace();
}
}
}
}

運行結果:

總結
1.在聲明時盡量指定長度。

2.ArrayList底層是數組,數組是適合查詢的,因為數組每個元素的內存空間是固定的,每次查詢時,只需要去查詢對應位置的內存空間,就可以很快找到相應的值。而數組不擅長的是添加和刪除。試想,集合長度是100000,而我們在第2個位置添加了一個元素,導致的結果是從第3個開始后面每一個元素都要往后串一個元素內存空間那么大的位置。刪除剛好相反,是向前串一個位置,這樣的效率是很低的,元素越多,效率越低。而頻繁的添加和刪除,適用鏈表——LinkedList。

總結

以上是生活随笔為你收集整理的ArrayList底层实现原理「建议收藏」的全部內容,希望文章能夠幫你解決所遇到的問題。

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