純手寫Arraylist集合框架
純手寫Arraylist集合框架 相關視訊教程 http://www.itmayiedu.com/front/couinfo/125/0
作者:螞蟻課堂創始人-餘勝軍
集合框架介紹
說明:對於以上的框架圖有如下幾點說明
1.所有集合類都位於java.util包下。Java的集合類主要由兩個介面派生而出:Collection和Map,Collection和Map是Java集合框架的根介面,這兩個介面又包含了一些子介面或實現類。
2. 集合介面:6個介面(短虛線表示),表示不同集合型別,是集合框架的基礎。
3. 抽象類:5個抽象類(長虛線表示),對集合介面的部分實現。可擴充套件為自定義集合類。
4. 實現類:8個實現類(實線表示),對介面的具體實現。
5.Collection 介面是一組允許重複的物件。
6.Set 介面繼承Collection,集合元素不重複。
7.List 介面繼承Collection,允許重複,維護元素插入順序。
8.Map介面是鍵-值物件,與Collection介面沒有什麼關係。
9.Set、List和Map可以看做集合的三大類:
List集合是有序集合,集合中的元素可以重複,訪問集合中的元素可以根據元素的索引來訪問。
Set集合是無序集合,集合中的元素不可以重複,訪問集合中的元素只能根據元素本身來訪問(也是集合裡元素不允許重複的原因)。
Map集合中儲存Key-value對形式的元素,訪問時只能根據每項元素的key來訪問其value。
List框架介面
List集合代表一個有序集合,集合中每個元素都有其對應的順序索引。List集合允許使用重複元素,可以通過索引來訪問指定位置的集合元素。
List介面繼承於Collection介面,它可以定義一個允許重複的有序集合。因為List中的元素是有序的,所以我們可以通過使用索引(元素在List中的位置,類似於陣列下標)來訪問List中的元素,這類似於Java的陣列。
List介面為Collection直接介面。List所代表的是有序的Collection,即它用某種特定的插入順序來維護元素順序。使用者可以對列表中每個元素的插入位置進行精確地控制,同時可以根據元素的整數索引(在列表中的位置)訪問元素,並搜尋列表中的元素。實現List介面的集合主要有:ArrayList、LinkedList、Vector、Stack。
ArrayList核心程式碼
Arraylist底層基於陣列實現
private Object[] elementData;
Arraylist底層預設陣列初始化大小為10個object陣列
public ExtArraylist() throws Exception {
this(10);
}
public ExtArraylist(intinitialCapacity) throws Exception {
if (initialCapacity < 0){
thrownewIllegalArgumentException("初始容量不能小於0 " + initialCapacity);
}
elementData = new Object[initialCapacity];
}
新增元素後大於當前陣列的長度,則進行擴容,將陣列的長度增加原來陣列的一半。
// 增大陣列空間
privatevoid grow(intminCapacity) {
// overflow-conscious code
intoldCapacity = elementData.length;
intnewCapacity = oldCapacity + (oldCapacity >>1); // 在原來容量的基礎上加上
// oldCapacity/2
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; // 最少保證容量和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);
}
純手寫Arraylist集合程式碼
/**
* 自定義 ArrayList集合<br>
* 作者: 每特教育-餘勝軍<br>
* 聯絡方式:QQ644064779|WWW.itmayiedu.com<br>
*/
public class ExtArrayList<E> implements ExtList<E> {
// ArrayList底層採用陣列存放
private Object[] elementData;
// 預設陣列容量
private static final int DEFAULT_CAPACITY = 10;
// 記錄實際ArrayList大小
private int size;
// ArrayList 指定 陣列初始的容量
public ExtArrayList(int initialCapacity) {
if (initialCapacity < 0) {
throw new IllegalArgumentException("初始容量不能小於0");
}
elementData = new Object[initialCapacity];
}
// 預設初始化容量為10;
public ExtArrayList() {
this(DEFAULT_CAPACITY);
}
// 執行緒安全問題ArrayList底層每次擴容是以1.5倍
public void add(E e) {
// 1.判斷實際存放的資料容量是否大於elementData容量
ensureExplicitCapacity(size + 1);
// 2.使用下標進行賦值
elementData[size++] = e;
}
public void add(int index, Object object) {
// 1.判斷實際存放的資料容量是否大於elementData容量
ensureExplicitCapacity(size + 1);
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = object;
size++;
}
// int minCapacity 最當前size+1
private void ensureExplicitCapacity(int minCapacity) {
if (size == elementData.length) {
// 原來本身elementData容量大小 2
int oldCapacity = elementData.length;
// 新資料容量大小 (oldCapacity >> 1)=oldCapacity/
int newCapacity = oldCapacity + (oldCapacity >> 1);// (2+2/2)=3
// 如果初始容量為1的時候,那麼他擴容的大小為多少呢?
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; // 最少保證容量和minCapacity一樣
// 將老陣列的值賦值到新陣列裡面去
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
// 使用下標獲取陣列元素
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}
public E remove(int index) {
// 1.使用下標查詢該值是否存在
E object = get(index);// index 2
// 計算刪除元素後面的長度
int numMoved = size - index - 1; // 5
// 2.刪除原理 使用arraycopy往前移動資料,將最後一個變為空
if (numMoved > 0)
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
elementData[--size] = null;// 將最後一個元素變為空
return object;
}
// 刪除相同元素刪除第一個
public boolean remove(Object object) {
for (int i = 0; i < elementData.length; i++) {
Object value = elementData[i];
if (value.equals(object)) {
remove(i);
return true;
}
}
return false;
}
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException("越界啦!");
}
public int getSize() {
return size;
}
}
最後總結
它底層使用的是陣列進行增刪和查詢。會定義全域性變數size,當增加元素時,執行size++,當刪除元素時,size--。這個size就是實際的集合大小
Add方法實現原理判斷實際要存放的容量是否大於elementData陣列的容量。如果大於則進行擴容,若小於則進行插入。插入時,要將該下標後面的資料全部後移。
Arraylist的Get方法實現原理
根據傳入的下標,到陣列中進行查詢。當然前提是下標值必須小於size。
相關文章
- 純手寫web框架Web框架
- 集合框架2- ArrayList框架
- Java集合框架(一)-ArrayListJava框架
- Java 集合框架(二)—— ArrayListJava框架
- Java 集合框架------ArrayList原始碼分析Java框架原始碼
- Java 集合框架 ArrayList 原始碼剖析Java框架原始碼
- 集合框架-ArrayList集合的toString()方法原始碼解析框架原始碼
- 集合框架原始碼學習之ArrayList框架原始碼
- 集合框架-集合的巢狀遍歷(HashMap巢狀ArrayList)框架巢狀HashMap
- 集合框架-集合的巢狀遍歷(ArrayList巢狀HashMap)框架巢狀HashMap
- 集合框架-ArrayList集合儲存自定義物件的排序案例框架物件排序
- 手寫ArrayList核心原始碼原始碼
- 手寫 ArrayList 核心原始碼原始碼
- Java集合——ArrayListJava
- JAVA集合-ArrayListJava
- 【集合框架】JDK1.8原始碼分析之ArrayList(六)框架JDK原始碼
- 面試必會之ArrayList原始碼分析以及手寫ArrayList面試原始碼
- Java 集合之ArrayListJava
- Java集合之ArrayListJava
- 【Java集合】2 ArrayListJava
- Java集合(一) —— ArrayListJava
- 【java】【集合】去除ArrayList中的元素、ArrayList巢狀ArrayListJava巢狀
- JDK7集合框架原始碼學習-ArrayList(0)JDK框架原始碼
- JDK7集合框架原始碼學習-ArrayList(1)JDK框架原始碼
- 集合-ArrayList 原始碼解析原始碼
- ArrayList集合底層原理
- 圖解集合1:ArrayList圖解
- 純手寫Promise,由淺入深Promise
- 手寫mybatis框架MyBatis框架
- JDK7集合框架原始碼學習-ArrayList(4)SubListJDK框架原始碼
- Java集合 ArrayList原理及使用Java
- 【Java集合】ArrayList原始碼分析Java原始碼
- Java Collection介面 ArrayList集合(容器)Java
- JAVA集合:ArrayList原始碼分析Java原始碼
- Java集合(三) ArrayList詳解Java
- 高手過招「效能優化/純手寫SpringMVC框架/MySql優化/微服務」優化SpringMVC框架MySql微服務
- 純手寫實現JDK動態代理JDK
- 集合框架-ArrayList儲存字串、自定義物件並遍歷泛型版框架字串物件泛型