List是有序且元素可重復集合
ArrayList
ArrayList實現(xiàn)了一個可變大小的數(shù)組,允許包含所有的元素按脚,包括null析桥。
由于ArrayList實現(xiàn)了List接口,所以ArrayList存儲的元素是有序授段,按照添加元素的先后順序進行排列。當然也可以通過Collections.sort(List<T> list);
對ArrayList內(nèi)的元素進行排序番甩,但需要注意該方法的泛型參數(shù)類型應該是Comparable類型侵贵,所以ArrayList中的元素需要實現(xiàn)Comparable
接口,并實現(xiàn)其int compareTo(T o)
方法
每一個ArrayList實例都會有一個初始容量Capacity缘薛,默認為10窍育,你可以在構造實例時根據(jù)需要設定改容量的大小,如下:
ArrayList arrayList = new ArrayList<Integer>(20);
在插入大量數(shù)據(jù)時掩宜,為了提升性能蔫骂,可以調(diào)用ArrayList
中的ensureCapacity(int minCapacity)
方法來增加ArrayList
容量,從而提高插入的效率牺汤。
需要注意的是辽旋,ArrayList
是非線程安全的,如果多個線程同時訪問同一個ArrayList
實例,并且其中至少有一個線程對ArrayList
實例進行了修改补胚,為了保證線程安全码耐,需要在外部實現(xiàn)同步。你也可以這樣創(chuàng)建一個同步的ArrayList
實例:
Collections.synchronizedList(new ArrayList<Integer>());
ArrayList
支持快速隨機訪問溶其,訪問某個元素的事件復雜度是O(1).但是插入和刪除元素的操作速度很慢骚腥。
CopyOnWriteArrayList
CopyOnWriteArrayList
同ArrayList
一樣,底層仍然是一個可變大小的數(shù)組實現(xiàn)的瓶逃,但CopyOnWriteArrayList
的不同卻在于其利用了高并發(fā)往往是讀多寫少的特性束铭,對讀操作不加鎖,對寫操作加鎖厢绝。
源碼中契沫,對于寫操作add(E e) | set(E e) | remove(int index)
,在進入方法后昔汉,首先加鎖懈万,然后復制一份新的數(shù)組,對新數(shù)組進行相應操作靶病,然后將新數(shù)組賦給舊的引用会通,然后再解鎖。
由于CopyOnWriteArrayList
在進行寫操作時娄周,對容器的基本數(shù)組進行了復制涕侈,內(nèi)存開銷會比較大,所以不適于存儲大數(shù)據(jù)量昆咽。
LinkedList
LinkedList
底層是一個鏈表的實現(xiàn)驾凶,因此在內(nèi)部有許多具有鏈表特色的方法,比如:
public void addFirst(E e)//在表頭插入元素
public void addLast(E e)//在表尾插入元素
public E getFirst()//獲取鏈表的頭(第一個)元素
public E getLast()//獲取鏈表的尾(最后一個)元素
public E pop()
public E push()
...
在這里就不一一介紹了掷酗。
LinkedList
是非線程安全的,這一點同ArrayList
是一樣的窟哺,獲取同步的LinkedList
泻轰,可以這樣做:
Collections.synchronizedList(new LinkedList<Integer>());
由于LinkedList
是鏈表結構的,所以其插入操作的時間復雜度是常量級的且轨,但是查找浮声、刪除和更新的操作是O(n)。
Vector
Vector
和ArrayList
非常相似旋奢,底層也是一個可變長的數(shù)組泳挥,但是Vector
是線程安全的,因此單純從性能尚來說至朗,Vector
的性能要低于ArrayList
屉符,但Vector
類中也提供了一些,去盡可能的提升性能,優(yōu)化內(nèi)存存儲
/*
構造方法矗钟,使用制定的初始容量和容量增量實例化對象
*/
public Vector(int initialCapacity, int capacityIncrement)
public int capacity()//返回當前容量
public void ensureCapacity (int minCapacity)//增加容量
public void trimToSize()//對實例的容量進行微調(diào)唆香,使其等于實例中元素的數(shù)量
Stack
Stack
是Vector
的子類,所以改類也是線程安全的吨艇。其實現(xiàn)了數(shù)據(jù)結構中棧躬它,具有元素后進先出(LIFO)的規(guī)則。具有通常的push
pop
和peek
操作东涡。
遍歷操作
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)部都不能對集合的結構進行修改
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的相同與不同
相同點:1>都可以對List集合進行遍歷冯吓。這兩個方法都是快速失敗的,也就是說除非調(diào)用迭代器內(nèi)部修改集合集合的方法疮跑,否則無論在何處無論在何時修改集合都會產(chǎn)生快速失敗桑谍,迭代器都會拋出ConcurrentModificationException
運行時異常。
不同點:2>iterator可以用于多種集合祸挪,set锣披、list、Map都可贿条,而listIterator只能用于list集合
3>兩者包含的方法不同雹仿。比如,ListIterator
中有add()
方法整以,而Iterator
中沒有
4>ListIterator
可以實現(xiàn)雙向遍歷胧辽,而Iterator
只能單向向后(next()
)遍歷