Java中的Queue與Deque

Queue接口的實現類

Queue接口做爲隊列數據結構,java在實現的時候,直接定義了Deque接口(雙端隊列)來繼承Queue接口,而且只實現Deque接口。這樣java中的雙端隊列就囊括了隊列、雙端隊列、堆棧(Deque接口又定義了Stack的操做方法)這3種角色的功能。java

因此咱們在使用的時候直接使用的是Deque接口的實現類,固然Deque接口繼承自Queue接口。數組

queue-1

Deque接口的實現類

咱們記住,Deque接口所能表明的數據結構:隊列,雙端隊列,堆棧。數據結構

ArrayDeque

deque-1

1.內部使用transient Object[] elements數組來實現。擁有head/tail這2個頭尾指針。最小初始化容量8。它仍是一個循環隊列。併發

queue-2

2.在擴容/初始化的時候,數組的內部大小必定是2個冪次方,也就是說大小隻多是:八、1六、3二、64這樣的倍增。spa

queue-3

queue-4

3.它做爲堆棧、隊列、雙端隊列的操做和LinkedList的操做是一致的,只是內部的實現不一樣。固然,它們也有區別。指針

ArrayDeque實現了雙端隊列,內部使用循環數組實現,這決定了它有以下特色:code

  • 在兩端添加、刪除元素的效率很高,動態擴展須要的內存分配以及數組拷貝開銷能夠被平攤,具體來講,添加N個元素的效率爲O(N)。
  • 根據元素內容查找和刪除的效率比較低,爲O(N)。
  • 與ArrayList和LinkedList不一樣,沒有索引位置的概念,不能根據索引位置進行操做(沒法隨機訪問,這也符合隊列的性質)。

4.操做示例,要記住,Deque具備3種數據結構的特性,不一樣的數據結構應該使用不一樣的語義化方法!對象

queue-5

queue-6

LinkedList

ll-1

LinkedList中在「List有序集合」這一篇文章中講過了,從隊列和雙端隊列的角度來看,LinkedList和ArrayDeque的方法聲明都是一致的。只不過LinkedList較之於ArrayDeque多實現了List接口,還具備有序集合List的特性。繼承

ArrayDeque和LinkedList的比較

ArrayDeque和LinkedList都實現了Deque接口,應該用哪個呢?若是隻須要Deque接口,從兩端進行操做,通常而言,ArrayDeque效率更高一些,應該被優先使用。不過,若是同時須要根據索引位置進行操做,或者常常須要在中間進行插入和刪除,則應該選LinkedList(注意,這裏使用的是List特性,而不是Deque特性了)。索引


PriorityQueue

有一個直接實現了Queue接口的類,可是它並非真正意義上的隊列,而是一個優先隊列

pq-1

PriorityQueue保存元素的順序並非按照加入的順序,而是根據元素的大小(實現Comparable接口或提供Comparator類)來決定元素在Queue隊列中的順序。默認狀況若是咱們存入String對象,則是按降序排列。

pq-2

能夠看到,優先隊列的默認大小爲11,內部使用Object[]數組來實現隊列結構。

pq-3

對於擴容操做,能夠看到。若是當前容量小於64,則容量增長2;若是當前容量大於等於64,則變爲原來的1.5倍。

講講Queue/Deque對應的併發類

  1. PriorityQueue優先隊列沒有對應的併發類。可是Queue接口有對應的併發實現類:java.util.concurrent.ConcurrentLinkedQueue類。
  2. Deque接口有對應的併發實現類:java.util.concurrent.ConcurrentLinkedDeque類。

Collection集合下的Queue/Deque

q-4

從類圖來看,實現了Queue接口的類就是PriorityQueue,但要注意它是優先隊列!實現了Deque接口的類有ArrayDeque和LinkedList,2者的內部實現不一樣,一個是數組,另外一個是鏈表。

相關文章
相關標籤/搜索