1. 程式人生 > >6.對比Vector、ArrayList、LinkedList有何區別以及常見的集合問題

6.對比Vector、ArrayList、LinkedList有何區別以及常見的集合問題

第6講:對比Vector、ArrayList、LinkedList有何區別

典型回答:

相同點:

  • 三者都是實現集合框架中的List,也就是所謂的有序集合,存取有序,有索引,可以重複,具體功能比較相似,都能實現增刪改查,都提供迭代器以遍歷其內容。

區別:

  • Vector是Java早期提供的執行緒安全的動態陣列,執行緒安全,增刪改查都比較慢。
  • ArrayList底層是陣列,執行緒不安全,查詢和修改快,增刪慢,使用get和set方法是花費常數時間的,但是如果插入元素和刪除元素,除非插入和刪除的位置都在表末尾,否則程式碼開銷會很大,因為裡面需要陣列的移動。與Vector類似,也是可以根據需要調整容量,不過二者的調整邏輯有所區別,Vector在擴容時提高1倍,而ArrayList則是增加50%
  • LinkedList是雙向連結串列實現的,執行緒不安全,所以get會非常消耗資源,除非位置離頭部很近,但是插入和刪除元素花費常數時間。

擴充套件知識

1.集合框架

  • List,有序集合,可重複,增刪改查
  • Set,無序不可重複
  • Queue/Deque,除了集合的功能,還支援類似的先入先出(FIFO)或者後入先出(LIFO)
2.Map和Set
  • TreeSet實際上是利用TreeMap實現的,Java類庫建立了一個Dummy物件”PRESENT”作為value,然後所有插入的物件是以鍵的形式放入了TreeMap裡面。
  • 同理,HashSet也是以HashMap為基礎實現的。
3.Set的一些使用說明
  • TreeSet支援自然順序訪問,但是新增、刪除、包含等操作相對要低效(log(n)時間)
  • HashSet則是利用Hash演算法,理想情況下,如果雜湊雜湊正常,可以提供常數時間的新增、刪除、包含等操作,但是不保證有序
  • LinkedhashSet,內部構建了一個記錄插入順序的雙向連結串列,因此提供了按照插入順序遍歷的能力,於此同時,也保證了常數時間的新增、刪除、包含等操作,這些效能略低於HashSet,因為需要維護這些連結串列的開銷。
  • 在遍歷列表時,HashSet效能受自身容量的影響,所以初始化時,除非有必要,不然不要將其背後的HashSet容量設定過大,而對於LinkedHashSet,由於其內部連結串列提供的方便,遍歷效能只和元素的多少有關。
4.Collections的synchronized方法
  • Collections工具類中,提供了一系列的synchronized方法,比如:List<T> synchronizedList(List<T> list) ,所以可以用類似的方法來實現基本的執行緒安全集合:List list =Collections.synchronizedList(new ArrayList()); 其實現就是將每個方法,比如get\set\add之類,都通過synchronized新增同步支援,簡單粗暴,但是也非常實用。這些方法建立的執行緒安全集合,都符合迭代是fail-fast行為,當發生意外的併發修改時,儘早丟擲ConcurrentModificationException 異常,以避免不可預期的行為
5.排序
  • 對於原始資料型別,目前使用的是所謂雙軸快速排序,是一種改進的快速排序演算法,早期版本是相對傳統的快速排序
  • 對於物件資料型別,目前則是使用TimSort,思想上也是一種歸併和二分插入排序(binarySort)結合的優化排序演算法。TimSort 並不是 Java 的獨創,簡單說它的思路是查詢資料集中已經排好序的分割槽(這裡叫 run),然後合併這些分割槽來達到排序的目的。
6.思考題

先思考一個應用場景,比如你需要實現一個雲端計算任務排程系統,希望可以保證 VIP 客戶的任務被優先處理,你可以利用哪些資料結構或者標準的集合型別呢?更進一步講,類似場景大多是基於什麼資料結構呢?

  • 自然就會想到優先順序隊列了,但還需要額外考慮vip再分級,即同等級vip的平權的問題,所以應該考慮除了直接的和vip等級相關的優先順序佇列優先順序規則問題,還得考慮同等級多個客戶互相不被單一客戶大量任務阻塞的問題。
  • 其實我覺得應該參考銀行視窗,同時三個視窗,就是三個佇列,銀臺就是消費者執行緒,某一個視窗vip優先,沒有vip時也為普通客戶服務。要實現,要麼有個dispatcher,要麼保持vip通道不許普通進入,vip櫃檯閒時從其他佇列分配過來普通客戶