1.vector和arraylist以及linkedlist區別和聯絡,以及分別的應用場景
執行緒安全
vector:
與arraylist一樣,也是通過陣列實現的,不同的它支援執行緒的同步,底層採用synchronized同步方法進行加鎖,所以執行緒安全;即某一時刻只有乙個執行緒能夠寫vector,避免多執行緒同時寫而引起的不一致性,但實現同步需要很高的花費,因此,訪問它比訪問arraylist慢;如果建立vector沒有執行容量,則預設容量為10;
arraylist:
它是最常用的list實現類,底層基於陣列,執行緒非安全,允許對元素進行快讀隨機訪問;資料的缺點就是每個元素之間不能有間隔,當資料大小不滿足時需要增加儲存能力,就要將已經有陣列的資料複製到新的儲存空間中。當從arraylist的中間位置插入或刪除元素時,需要對陣列進行複製,移動,代價比較高。因此,它的查詢和修改效率高,增加和刪除效率低;
-底層雙向鍊錶結構,執行緒非安全,查詢和修改效率低,但是增加和刪除效率高;另外,它還提供了list介面中沒有定義的方法,專門用於操作表頭和表尾元素,可以當作堆疊,佇列和雙向佇列使用;
使用場景
vector很少用;
如果有大量的新增和刪除則可以選擇linkedlist;
如果有大量的查詢和修改則可以選擇arraylist;
2.1 自己編寫乙個arraylist集合類,根據業務一般來說,add/set/remove加鎖;
2.2 利用list list=collections.synchronizedlist(new arraylist<>()); 採用synchronized加鎖
public e get
(int index)
}public e set
(int index, e element)
}public
void
add(
int index, e element)
}public e remove
(int index)
}
2.3 new copyonwritearraylist<>().add(" "); 採用reentrantlock加鎖
public
boolean
add(e e)
finally
}
3.1 copyonwritearraylist底層實現:
copyonwritearraylist在執行修改操作的時候,會複製乙份新的陣列資料,代價昂貴,修改過來將原來的集合指向新的集合完成操作;
3.1.1 add新增:
在新增的時候是需要加鎖的,否則多執行緒寫的時候會copy出n個副本出來;使用reentrantlock保證多執行緒環境下的集合安全;
public
boolean
add(e e)
finally
}
3.1.2 get讀取:
讀的時候沒有加鎖,如果讀的時候有多個執行緒正在向copyonwritearraylist新增資料,讀還是會讀到舊的資料,因為寫的時候不會鎖住舊的copyonwritearraylist;
public e get
(int index)
copyonwritearraylist應用場景:
適用於讀取操作遠大於寫操作場景(底層get讀取沒有加鎖,直接獲取)
3.2 collections.synchronizedlist幾乎底層方法都加上了synchronized的鎖;
場景:
寫操作的效能比copyonwritearraylist要好,但是讀取的效能不如copyonwritearraylist;
設計思想:讀寫分離,最終一致;
缺點:
記憶體占用問題:由於寫時複製,記憶體中就會出現兩個物件占用空間,如果物件大則容易發生young gc和full gc;
資料一致問題:copyonwritearraylist容器只能保證資料最終一致性,不能保證資料實時一致性;
1.7以及之前版本jdk,預設的大小為10;
1.8版本集合大小如果建立時沒有指定,則預設為0;若已經指定集合大小,則初始值為當前指定的大小;
當第一次新增資料的時候,集合大小擴容為10,第二次以及後續每次按照int oldcapacity=elementdata.length; newcapacity = oldcapacity+(oldcapacity>>1),就是其容量擴充套件為原來容量的1.5倍;
5.1 屬性
預設初始值的大小:
private
static
final
int default_capacity =
10;
預設的空物件陣列:
private
static
final object[
] defaultcapacity_empty_elementdata =
;
實際儲存資料的陣列:
transient object[
] elementdata;
5.2 無參構造器
public
arraylist()
5.3 擴容機制
public
boolean
add(e e)
private
void
ensurecapacityinternal
(int mincapacity)
ensureexplicitcapacity
(mincapacity);}
//ensurecapacityinternal方法接受了size+1作為mincapacity,並且判斷如果陣列是空陣列,那麼10和mincapacity的較大值就作為新的mincapacity。
複製**
複製**
private
void
ensureexplicitcapacity
(int mincapacity)
//判斷傳入的mincapacity和elementdata.length的大小,如果elementdata.length大於mincapacity,說明陣列容量夠用,就不需要進行擴容,
//反之,則傳入mincapacity到grow()方法中,進行擴容
private
void
grow
(int mincapacity)
進入grow()方法,會將newcapacity設定為舊容量的1.5倍,這也是arraylist每次擴容都為原來的1.5倍的由來。然後進行判斷,如果newcapacity小於mincapacity,那麼就將mincapacity的值賦予newcapacity。
然後在檢查新容量是否超出了定義的容量,如果超出則呼叫hugecapacity方法,比較mincapacity和max_array_size的值;如果mincapacity大,那麼新容量為integer。max_value,否則新容量為max_arraysize。最後呼叫arrays.cpoyof傳遞elementdata和新容量,返回新的elementdata;
資料結構 單列集合 List集合 Set集合
1 陣列特點 查詢快 位址是連續的,通過首位址可以找到陣列,通過索引 可以快速查詢某個元素 增刪慢 陣列的長度是固定的,要增刪某個元素,必須重新建立乙個陣列,把資料複製過來 2 arraylist特點 底層也是使用陣列實現,兼具陣列的特點 3 linkedlist特點 底層是鍊錶結構 增刪快 因為如...
JAVA單列集合
list e 介面 vector類 set e 介面 hashset e 類 例項treeset e 類 arraylist e 類 linkedlist 類 public class collection public static void demo9 public static void de...
java 單列集合複習
package cn.itcast.map 單例集合 的體系 collection 單例集合的根介面 list 如果是實現了list介面的集合類,具備的特點 有序,重複。arrarylist 底層 是使用了object陣列實現的,特點 查詢速度快,增刪慢。linkedlist 底層是使用了鍊錶資料結...