Java集合:List集合
List集合
List集合類中元素有序、且可重復(fù),集合中的每個(gè)元素都有其對(duì)應(yīng)的順序索引。
List容器中的元素都對(duì)應(yīng)一個(gè)整數(shù)型的序號(hào)記載其在容器中的位置,可以根據(jù)序號(hào)存取容器中的元素。
JDK API中List接口的實(shí)現(xiàn)類常用的有:ArrayList、LinkList和Vector。
List集合里添加了一些根據(jù)索引來操作集合元素的方法
一、ArrayList
ArrayList是List接口的典型實(shí)現(xiàn)類,本質(zhì)上,ArrayList是對(duì)象引用的一個(gè)變長數(shù)組。
ArrayList是List接口的可變數(shù)組的實(shí)現(xiàn)。實(shí)現(xiàn)了所有可選列表操作,并允許包括null在內(nèi)的所有元素。除了實(shí)現(xiàn)List接口外,此類還提供了一些方法來操作內(nèi)部用來存儲(chǔ)列表的數(shù)組的大小。
每個(gè)ArrayList實(shí)例都有一個(gè)初始容量,該容量用來儲(chǔ)存列表元素的數(shù)組大小。默認(rèn)初始容量為10。
ArrayList底層采用數(shù)組實(shí)現(xiàn)。數(shù)組都有一個(gè)重大的缺陷,這就是從數(shù)組的中間位置刪除一個(gè)元素要付出很大的代價(jià),其原因是數(shù)組中處于被刪除元素之后的所有元素都要向數(shù)組的前端移動(dòng)。在數(shù)組中間位置插入一個(gè)元素也是如此(數(shù)據(jù)的copy)。
注:Arrays.asList(…) 方法返回的 List 集合既不是 ArrayList 實(shí)例,也不是 Vector 實(shí)例。 Arrays.asList(…)返回值是一個(gè)固定長度的 List 集合。
1.ArrayList的存取實(shí)現(xiàn)
1.1存儲(chǔ):
ArrayList提供了一下添加元素的方法
**add(E element)**方法,將指定的元素添加到列表的尾部
**add(int index, E element)**方法,將指定的元素插入此列表的指定位置,如果當(dāng)前位置有元素,則向右移動(dòng)當(dāng)前位于該位置的元素以及所有后續(xù)元素(將其索引值加1)
**set(int index, E element)**方法,替換數(shù)組中已經(jīng)存在的元素內(nèi)容
**addAll(Collection<? extends E> c)**方法,按照指定Collection的迭代器所返回的元素順序,將該Collection中的所有元素添加到此列表的尾部。
**addAll(int index, Collection<? extends E> c)**方法,從指定的位置開始,將指定collection中的所有元素插入到此列表中
1.2讀取:
**get(int index)**方法,獲取指定位置上的元素
2.總結(jié)
- ArrayLlist內(nèi)部是由數(shù)組來實(shí)現(xiàn)的。在存放數(shù)據(jù)的數(shù)組長度不夠時(shí),會(huì)進(jìn)行擴(kuò)容,即增加數(shù)組長度。擴(kuò)展為原來的1.5倍。
- 由于是數(shù)組來實(shí)現(xiàn),所以,優(yōu)點(diǎn)是查找元素很快。可以通過下標(biāo)查找元素,查找效率高。缺點(diǎn)是每次添加和刪除元素都會(huì)進(jìn)行大量的數(shù)組元素移動(dòng)。長度不夠會(huì)擴(kuò)容。效率底下。
- ArrayList每次的增、刪、改操作都伴隨著數(shù)組的復(fù)制和元素的移動(dòng)。這意味著新的內(nèi)存空間的開辟。
二、LinkedList
LinkedList其實(shí)也就是我們?cè)跀?shù)據(jù)結(jié)構(gòu)中的鏈表,這種數(shù)據(jù)結(jié)構(gòu)有這樣的特性:
- 分配內(nèi)存空間不是必須是連續(xù)的;
- 插入、刪除操作很快,只要修改前后指針就OK了,時(shí)間復(fù)雜度為O(1);
- 訪問比較慢,必須得從第一個(gè)元素開始遍歷,時(shí)間復(fù)雜度為O(n);
在Java中,LinkedList提供了豐富的方法,可以模擬鏈?zhǔn)疥?duì)列,鏈?zhǔn)蕉褩5葦?shù)據(jù)結(jié)構(gòu),為用戶帶來了極大的方便,下面看看這些方法的用法:
add:
boolean add(E e):在鏈表后添加一個(gè)元素,如果成功,返回true,否則返回false; void addFirst(E e):在鏈表頭部插入一個(gè)元素; addLast(E e):在鏈表尾部添加一個(gè)元素; void add(int index, E element):在指定位置插入一個(gè)元素。remove:
E remove();移除鏈表中第一個(gè)元素; boolean remove(Object o):移除鏈表中指定的元素; E remove(int index):移除鏈表中指定位置的元素; E removeFirst():移除鏈表中第一個(gè)元素,與remove類似; E removeLast():移除鏈表中最后一個(gè)元素; boolean removeFirstOccurrence(Object o):移除鏈表中第一次出現(xiàn)所在位置的元素; boolean removeLastOccurrence(Object o):移除鏈表中最后一次出現(xiàn)所在位置的元素;get:
E get(int index):按照下邊獲取元素; E getFirst():獲取第一個(gè)元素; E getLast():獲取最后一個(gè)元素;push、pop、poll:
void push(E e):與addFirst一樣,實(shí)際上它就是addFirst; E pop():與removeFirst一樣,實(shí)際上它就是removeFirst; E poll():查詢并移除第一個(gè)元素;push,pop的操作已經(jīng)很接近stack的操作了。如果鏈表為空的時(shí)候,poll返回null,而pop則產(chǎn)生異常。
peek:
E peek():獲取第一個(gè)元素,但是不移除; E peekFirst():獲取第一個(gè)元素,但是不移除; E peekLast():獲取最后一個(gè)元素,但是不移除offer:
boolean offer(E e):在鏈表尾部插入一個(gè)元素; boolean offerFirst(E e):與addFirst一樣,實(shí)際上它就是addFirst; boolean offerLast(E e):與addLast一樣,實(shí)際上它就是addLast;其他:
boolean contains(Object o) 如果此列表包含指定的元素方法返回true。 E element() 此方法返回此列表的頭部 E set(int index,E element) 此方法替換在與指定元素在此列表中指定位置的元素。 subList(int index, int index) 方法是在給定的ArrayList集合中獲取給定下標(biāo)的子集合。注意范圍是[)。三、Vector
Vector 可實(shí)現(xiàn)自動(dòng)增長的對(duì)象數(shù)組。
java.util.vector提供了向量類(Vector)以實(shí)現(xiàn)類似動(dòng)態(tài)數(shù)組的功能。
創(chuàng)建了一個(gè)向量類的對(duì)象后,可以往其中隨意插入不同類的對(duì)象,即不需顧及類型也不需預(yù)先選定向量的容量,并可以方便地進(jìn)行查找。
對(duì)于預(yù)先不知或者不愿預(yù)先定義數(shù)組大小,并且需要頻繁地進(jìn)行查找,插入,刪除工作的情況,可以考慮使用向量類。
向量類提供了三種構(gòu)造方法:
public vector() public vector(int initialcapacity,int capacityIncrement) public vector(int initialcapacity)使用第一種方法系統(tǒng)會(huì)自動(dòng)對(duì)向量進(jìn)行管理,若使用后兩種方法,則系統(tǒng)將根據(jù)參數(shù),initialcapacity設(shè)定向量對(duì)象的容量(即向量對(duì)象可存儲(chǔ)數(shù)據(jù)的大小),當(dāng)真正存放的數(shù)據(jù)個(gè)數(shù)超過容量時(shí)。系統(tǒng)會(huì)擴(kuò)充向量對(duì)象存儲(chǔ)容量。
參數(shù)capacityincrement給定了每次擴(kuò)充的擴(kuò)充值。當(dāng)capacityincrement為0的時(shí)候,則每次擴(kuò)充一倍,利用這個(gè)功能可以優(yōu)化存儲(chǔ)。
在Vector類中提供了各種方法方便用戶的使用:
1.插入功能
(1)public final synchronized void adddElement(Object obj)
將obj插入向量的尾部。obj可以是任何類型的對(duì)象。對(duì)同一個(gè)向量對(duì)象,亦可以在其中插入不同類的對(duì)象。但插入的應(yīng)是對(duì)象而不是數(shù)值,所以插入數(shù)值時(shí)要注意將數(shù)組轉(zhuǎn)換成相應(yīng)的對(duì)象。
(2)public final synchronized void setElementAt(Object obj,int index)
將index處的對(duì)象設(shè)置成obj,原來的對(duì)象將被覆蓋。
(3)public final synchronized void insertElementAt(Object obj,int index)
在index指定的位置插入obj,原來對(duì)象以及此后的對(duì)象依次往后順延。
2.刪除功能
(1)public final synchronized void removeElement(Object obj)
從向量中刪除obj,若有多個(gè)存在,則從向量頭開始試,刪除找到的第一個(gè)與obj相同的向量成員。
(2)public final synchronized void removeAllElements();
刪除向量所有的對(duì)象
(3)public fianl synchronized void removeElementAt(int index)
刪除index所指的地方的對(duì)象
3.查詢搜索功能
(1)public final int indexOf(Object obj)
從向量頭開始搜索obj,返回所遇到的第一個(gè)obj對(duì)應(yīng)的下標(biāo),若不存在此obj,返回-1.
(2)public final synchronized int indexOf(Object obj,int index)
從index所表示的下標(biāo)處開始搜索obj.
(3)public final int lastIndexOf(Object obj)
從向量尾部開始逆向搜索obj.
(4)public final synchornized int lastIndex(Object obj,int index)
從index所表示的下標(biāo)處由尾至頭逆向搜索obj.
(5)public final synchornized firstElement()
獲取向量對(duì)象中的首個(gè)obj
(6)public final synchornized Object lastElement()
獲取向量對(duì)象的最后一個(gè)obj
4.其他功能
(1)public final int size();
此方法用于獲取向量元素的個(gè)數(shù)。它們返回值是向量中實(shí)際存在的元素個(gè)數(shù),而非向量容量。可以調(diào)用方法capacity()來獲取容量值。
(2)public final synchronized void setSize(int newsize);
此方法用來定義向量的大小,若向量對(duì)象現(xiàn)有成員個(gè)數(shù)已經(jīng)超過了newsize的值,則超過部分的多余元素會(huì)丟失。
程序中定義Enumeration類的一個(gè)對(duì)象Enumeration是java.util中的一個(gè)接口類,
(3)public final synchronized Enumeration elements();
此方法將向量對(duì)象對(duì)應(yīng)到一個(gè)枚舉類型。java.util包中的其他類中也都有這類方法,以便于用戶獲取對(duì)應(yīng)的枚舉類型。
在Enumeration中封裝了有關(guān)枚舉數(shù)據(jù)集合的方法。
方法 hasMoreElement() 來判斷集合中是否還有其他元素。
? 方法 nextElement() 來獲取下一個(gè)元素
PS:同時(shí)也有一個(gè)結(jié)論 Vector是有序的,可以重復(fù)的。
四、ArrayList、LinkedList、Vector的底層實(shí)現(xiàn)和區(qū)別
List 有序, 可重復(fù), 有索引。三者均為可伸縮數(shù)組。
ArrayList:底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組結(jié)構(gòu)。 線程不安全的。 所以ArrayList的出現(xiàn)替代了Vector, 但是查詢的速度很快。默認(rèn)擴(kuò)充為原來的1.5倍。
LinkedList:底層是鏈表數(shù)據(jù)結(jié)構(gòu)。 線程不安全的, 同時(shí)對(duì)元素的增刪操作效率很高。但查詢慢。
Vector:底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組結(jié)構(gòu)。 jdk1.0版本。 線程安全的。 無論增刪還是查詢都非常慢。默認(rèn)擴(kuò)充為原來的2倍。
Vector 和 ArrayList都是基于存儲(chǔ)元素的Object[ ] array來實(shí)現(xiàn)的。
LinkedList是采用雙向列表來實(shí)現(xiàn)的。
1、 線程同步,Vector線程安全,ArrayList線程不安全。
2、 效率問題,Vector效率低,ArrayList效率高。
3、 增長數(shù)量,Vector以1.5倍增長,ArrayList以2倍增長。
List集合子類Vector這個(gè)類已經(jīng)不常用了, 我就說里面的一個(gè)方法, Elements方法, 這個(gè)方法的返回值是枚舉接口, 里面有兩個(gè)方法, 判斷和獲取。此接口Enumeration的功能與 Iterator 接口的功能是重復(fù)的。Enumeration的名稱和方法的名稱過程, 書寫很麻煩。 所以被Iterator所取代。
ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于雙線鏈表的數(shù)據(jù)結(jié)構(gòu)。
ArrayList可以隨機(jī)定位對(duì)于新增和刪除操作add和remove,LinedList比較占優(yōu)勢(shì)
具有Collection接口必備的iterator()方法外,List還提供一個(gè)listIterator()方法ListIterator多了一些add()之類的方法,允許添加,刪除,設(shè)定元素,還能向前或向后遍歷。
Vector與ArrayList唯一的區(qū)別是,Vector是線程安全的,即它的大部分方法都包含有關(guān)鍵字synchronized,因此,若對(duì)于單一線程的應(yīng)用來說,最好使用ArrayList代替Vector,因?yàn)檫@樣效率會(huì)快很多(類似的情況有StringBuffer線程安全的與StringBuilder線程不安全的);而在多線程程序中,為了保證數(shù)據(jù)的同步和一致性,可以使用Vector代替ArrayList實(shí)現(xiàn)同樣的功能。
總結(jié)
以上是生活随笔為你收集整理的Java集合:List集合的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: awk教程入门与实例练习(一)
- 下一篇: JDK源码解析之 Java.lang.C