Java中的集合(二):List

List是有序且元素可重復(fù)集合

ArrayList

ArrayList實(shí)現(xiàn)了一個(gè)可變大小的數(shù)組,允許包含所有的元素,包括null。
  由于ArrayList實(shí)現(xiàn)了List接口,所以ArrayList存儲(chǔ)的元素是有序,按照添加元素的先后順序進(jìn)行排列。當(dāng)然也可以通過(guò)Collections.sort(List<T> list);對(duì)ArrayList內(nèi)的元素進(jìn)行排序,但需要注意該方法的泛型參數(shù)類(lèi)型應(yīng)該是Comparable類(lèi)型,所以ArrayList中的元素需要實(shí)現(xiàn)Comparable接口,并實(shí)現(xiàn)其int compareTo(T o)方法
  每一個(gè)ArrayList實(shí)例都會(huì)有一個(gè)初始容量Capacity,默認(rèn)為10,你可以在構(gòu)造實(shí)例時(shí)根據(jù)需要設(shè)定改容量的大小,如下:
ArrayList arrayList = new ArrayList<Integer>(20);
在插入大量數(shù)據(jù)時(shí),為了提升性能,可以調(diào)用ArrayList中的ensureCapacity(int minCapacity)方法來(lái)增加ArrayList容量,從而提高插入的效率。
  需要注意的是,ArrayList是非線程安全的,如果多個(gè)線程同時(shí)訪問(wèn)同一個(gè)ArrayList實(shí)例,并且其中至少有一個(gè)線程對(duì)ArrayList實(shí)例進(jìn)行了修改,為了保證線程安全,需要在外部實(shí)現(xiàn)同步。你也可以這樣創(chuàng)建一個(gè)同步的ArrayList實(shí)例:
Collections.synchronizedList(new ArrayList<Integer>());
  ArrayList支持快速隨機(jī)訪問(wèn),訪問(wèn)某個(gè)元素的事件復(fù)雜度是O(1).但是插入和刪除元素的操作速度很慢。

CopyOnWriteArrayList

CopyOnWriteArrayListArrayList一樣,底層仍然是一個(gè)可變大小的數(shù)組實(shí)現(xiàn)的,但CopyOnWriteArrayList的不同卻在于其利用了高并發(fā)往往是讀多寫(xiě)少的特性,對(duì)讀操作不加鎖,對(duì)寫(xiě)操作加鎖。
  源碼中,對(duì)于寫(xiě)操作add(E e) | set(E e) | remove(int index),在進(jìn)入方法后,首先加鎖,然后復(fù)制一份新的數(shù)組,對(duì)新數(shù)組進(jìn)行相應(yīng)操作,然后將新數(shù)組賦給舊的引用,然后再解鎖。
  由于CopyOnWriteArrayList在進(jìn)行寫(xiě)操作時(shí),對(duì)容器的基本數(shù)組進(jìn)行了復(fù)制,內(nèi)存開(kāi)銷(xiāo)會(huì)比較大,所以不適于存儲(chǔ)大數(shù)據(jù)量。

LinkedList

LinkedList底層是一個(gè)鏈表的實(shí)現(xiàn),因此在內(nèi)部有許多具有鏈表特色的方法,比如:

public void addFirst(E e)//在表頭插入元素
public void addLast(E e)//在表尾插入元素
public E getFirst()//獲取鏈表的頭(第一個(gè))元素
public E getLast()//獲取鏈表的尾(最后一個(gè))元素
public E pop()
public E push()
...

在這里就不一一介紹了。
  LinkedList是非線程安全的,這一點(diǎn)同ArrayList是一樣的,獲取同步的LinkedList,可以這樣做:
Collections.synchronizedList(new LinkedList<Integer>());
  由于LinkedList是鏈表結(jié)構(gòu)的,所以其插入操作的時(shí)間復(fù)雜度是常量級(jí)的,但是查找、刪除和更新的操作是O(n)。

Vector

VectorArrayList非常相似,底層也是一個(gè)可變長(zhǎng)的數(shù)組,但是Vector是線程安全的,因此單純從性能尚來(lái)說(shuō),Vector的性能要低于ArrayList,但Vector類(lèi)中也提供了一些,去盡可能的提升性能,優(yōu)化內(nèi)存存儲(chǔ)

/*
構(gòu)造方法,使用制定的初始容量和容量增量實(shí)例化對(duì)象
*/
public Vector(int initialCapacity, int capacityIncrement)

public int capacity()//返回當(dāng)前容量

public void  ensureCapacity (int minCapacity)//增加容量

public void trimToSize()//對(duì)實(shí)例的容量進(jìn)行微調(diào),使其等于實(shí)例中元素的數(shù)量

Stack

StackVector的子類(lèi),所以改類(lèi)也是線程安全的。其實(shí)現(xiàn)了數(shù)據(jù)結(jié)構(gòu)中棧,具有元素后進(jìn)先出(LIFO)的規(guī)則。具有通常的push poppeek操作。

遍歷操作

ArrayList<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    list.add(6);

1.foreach遍歷的方式

for(Integer i : list){
    System.out.println(i);
}

2.普通for循環(huán)遍歷的方式

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

注意前兩種方式在循環(huán)內(nèi)部都不能對(duì)集合的結(jié)構(gòu)進(jìn)行修改
  3.iterator遍歷的方式

Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
    System.out.println(iterator.next());
}

4.listIterator遍歷的方式

ListIterator<Integer> listIterator = list.listIterator();
while(listIterator.hasNext()){
    System.out.println(listIterator.next());
}

iterator和listIterator的相同與不同
相同點(diǎn):1>都可以對(duì)List集合進(jìn)行遍歷。這兩個(gè)方法都是快速失敗的,也就是說(shuō)除非調(diào)用迭代器內(nèi)部修改集合集合的方法,否則無(wú)論在何處無(wú)論在何時(shí)修改集合都會(huì)產(chǎn)生快速失敗,迭代器都會(huì)拋出ConcurrentModificationException運(yùn)行時(shí)異常。
不同點(diǎn):2>iterator可以用于多種集合,set、list、Map都可,而listIterator只能用于list集合
3>兩者包含的方法不同。比如,ListIterator中有add()方法,而Iterator中沒(méi)有
4>ListIterator可以實(shí)現(xiàn)雙向遍歷,而Iterator只能單向向后(next())遍歷

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容