前言:順序表是線性表的一種,它是較于數組更加靈活的一種儲存方式。線性表通常是邏輯上是連續的一條直線,但在物理上不是連續的。java中已經實現好了一個順序表,搭配泛型可以支持各種類型的使用,下面就來介紹該如何使用。
ArrayList簡介
在集合框架中,ArrayList是一個普通的類,實現了List接口。
ArrayList是以泛型方式實現的,使用必須先實例化。底層邏輯是一段連續的空間,可以支持動態擴容,是一個動態類型順序表。
和Vector不同,ArrayList不是線程安全,在單線程可以使用,多線程得選擇Vector或CopyOnWriteArrayList。
ArrayList內部實現
ArrayList內部:
可以看到,list內部有幾個重要的成員變量:
ArrayList擴容機制
在使用add來進行擴容時,我們可以看到是由上述圖來實現1.5倍的擴容,在插入元素的時候會自動檢測擴容。
ArrayList的構造方法
ArrayList(int initialCapacity)
指定順序表初始容量
給定一個形參,他會初始化一個指定初始化容量大小的類型數組,用來存放數據。
看看內部實現:
這個非常好理解,可以看見,要是給定的大小合法,則會直接創立一個新對象數組來賦給ArrayList的成員變量elementData(ArrayList操作的時候都是使用該數組)若是給定大小為零,則直接傳一個ArrayList的成員變量的空數組。若是給定大小小于零,則直接報錯。
ArrayList(Collection <? extends E>c)
利用其他Collection來構建ArrayList
我們可以看到,使用這個構造方法可以直接初始化構建一個順序表。
內部實現:
這里的“?”代表通配符,整體意思就是:
1.<>里面只要實現了Collection接口都是可以傳參的,如:
上述的圖片中可以看到List實現了Collection接口,所有實現了Collection接口的都可以傳入
2.這里的E代表著通配符的上界,意味著要么是E要么是c(E的子類)
經上述的細節之后,才能真正初始化構建一個帶有順序表的順序表。
ArrayList()
無參構造
直接創立的無參順序表
可以看見,內部只有簡簡單單的一個賦值,賦的是空的數組。
但是,我們可以使用add方法來初始化一下順序表。使用add方法時(如上述ArrayList擴容機制講到),采用的是擴容的方法來幫助這個空表初始化,通常默認為10,也就實現了該順序表為空的狀態。
ArrayList常見操作
如圖:
這里只演示比較容易出錯的的方法:
1.remove(int ···) 和 remove(Object ···)
第一個通俗易懂,就是刪除下標,但是第二個就容易和第一個混淆。比如在Integer類型順序表中,系統會無法分辨傳入的是下標還是元素:
所以第二個remove通常是這樣寫:
2.subList(int···,int···)
這個是截取部分內容(前閉后開區間),但注意的是,截取后并不會建立新的對象,只是拿到了截取到部分的地址而已:
ArrayList遍歷方法
有三種方法可以遍歷:
for - i:
for - each:
迭代器(iterator ,listIterator):
倆個迭代器的區別在于一個需要傳入元素個數參數,一個不用。一個可以實現從后往前迭代,一個不能。