前言:
此篇文章講解ArrayList和LinkedList底層實現原理、for和foreach遍歷集合哪個效率會更高一些!
講講什么是集合框架?集合框架是為表示和操作集合而規定的一種統一的標准的體系結構。任何集合框架都包含三大塊內容:對外的接口、接口的實現和對集合運算的算法。
沒學集合框架之前我們存儲多個數據是采用數組實現的,但是我們要創建數組的話先要初始化數組容量
這個時候我們可以使用到集合框架了 List 集合框架接口:
集合框架結構圖
List接口
public interface List<E> extends Collection <E>{}
List接口中存儲元素的特點:
List中存儲的元素實現類排序,而且可以重復的存儲相關元素。
(1)ArrayList:
優點:操作讀取操作效率高,基於數組實現的,可以為null值,可以允許重復元素,有序,異步。
缺點:由於它是由動態數組實現的,不適合頻繁的對元素的插入和刪除操作,因為每次插入和刪除都需 要移動數組中的元素。
(2)LinkedList:
優點:LinkedList由雙鏈表實現,增刪由於不需要移動底層數組數據,其底層是鏈表實現的,只需要修改鏈表節點指針,對元素的插入和刪除效率較高。
缺點: 遍歷效率較低。HashMap和雙鏈表也有關系。
ArrayList成員變量
LinkeList成員變量
圖截的不好,望包涵,手有點抖
聊聊ArrayList和LinkeList的底層數據結構
先談談LinkedList底層數據結構
話不多說先上圖
-- 具有頭節點和尾節點的雙鏈表
-- 附上一張別人的畫圖(若有侵權請及時聯系作者刪除)
作者是個手殘黨畫得扭扭曲曲的
雙鏈表是鏈表的一種,它的每個數據結點中都有兩個指針,分別指向直接后繼和直接前驅。所以,從雙向鏈表中的任意一個結點開始,都可以很方便地訪問它的前驅結點和后繼結點。一般我們都構造雙向循環鏈表。所以刪除和插入元素只需要修改鏈表節點指針就可以了,不像ArrayList一樣,ArrayList底層使用數組實現的,每一次刪除或修改數組都會移動元素。
談談ArrayList底層數據結構
ArrayList底層由數組實現,在實例化一個ArrayList時沒給予構造函數數組個數參數,集合中的數組默認是10的容量,在調用add方法時如果容量已滿,會將數組的容量擴大1.5倍的容量 如圖1
如果有興趣的同學,可以試下實現一個MyArratList,多看看內部實現原理,便更能隨心所欲的使用它。
給大家扯扯ArrayList和LinkeList的add添加元素的內部實現
List接口中有有很多的接口方法,如size()、isEmpty()、clear()等等.....,我就不一 一寫這么多了。
ArrayList的添加元素方法
1,先從add方法說起,執行add方法里面會先執行 ensureCapacity() 方法,先講講它是干嘛的吧!主要是確保數組的容量是否能繼續添加元素,未聲明集合容量的話,默認是 為10的,所以一當可用容量滿后將會把數組容量擴大1.5倍。
2,講講ensureCapacity()方法,當(元素數量+1)大於 數組長度時,會將容量擴大1.5倍,先創建一個新數組來存放數據,再擴大數組容量,最后拷貝到 elementData 數組中。
LinkedList的添加元素方法
1,LinkedList底層使用鏈表實現,實現添加刪除元素操作會比ArrayList效率高很多,LinkedList添加只需改變最后節點的指向即可,不會改變或挪動其他的元素。
-- 往鏈表中添加元素圖
使用for循環遍歷效率高還是foreach(增強式循環)?
1,for語法
for (int i = 0; i < integers.length; i++) {
System.out.println(intergers[i]);
}
2,foreach 語法
for(Integer in : integers){
System.out.println(in);
}
1,使用for適合循環ArrayLIst以及數組,當大批量的循環LinkedList時程序將會卡死,for適合循環數組結構,通過下標去遍歷。
2,使用foreach適合循環LinkedList,使用雙鏈表結構實現的應當使用foreach循環。