4 Queue隊列
前面幾篇,我們介紹了Java集合中常用到的對象。本篇中,我們再來說說Queue隊列的故事。
對于Queue,或許你跟我一樣,并不會將其與集合框架聯(lián)系到一起,更多時候是將其歸屬到數(shù)據(jù)結(jié)構(gòu)中。
尤其是查找集合相關的教程時,大多都是List、Set、Map,講解Queue隊列的很少出現(xiàn)。
但,當你真正去了解、看源碼時,會發(fā)現(xiàn)Queue是Collection的一個子接口,與List、Set同一級別;
題外話說多了,到底什么是Queue,讓我們來看!
1. Queue
Queue是Java集合框架中的一員,繼承于Collection接口。
與List、Set相同的是,Queue也實現(xiàn)了一種數(shù)據(jù)結(jié)構(gòu),這就是隊列(這也是Queue經(jīng)常出現(xiàn)在數(shù)據(jù)結(jié)構(gòu)相關文章中的主要原因)。
所以,要想明白Queue集合,首先得知道隊列是什么!
隊列是計算機中的一種數(shù)據(jù)結(jié)構(gòu),保存在其中的數(shù)據(jù)具有“先進先出(FIFO,First In First Out)”的特性。
如果,你不明白“先進先出”是什么,試想下排隊的場景,最先進來的人解決完問題后,最早離開---這就叫“先進先出”;
當隊伍中有新來的人時,需要排在隊伍的末端;而當隊伍中有人解決完問題時,會從隊伍的前端離開。
在隊列中,我們管隊伍的末端叫做“隊尾”,管隊伍的前端叫“隊頭”;新來的人,稱之為“入隊”。而離開的人,稱之為“出隊”;
稍有不同的是,在數(shù)據(jù)結(jié)構(gòu)中,隊列不支持從隊伍的中間插入和離開,只能從頭尾進行。而真實生活中,我們的隊伍可沒有這么和諧!!!!
還有一點是,當沒有人在排隊時,我們稱之為“空隊”,也就是隊列為空的情況。
通過介紹排隊的場景,讓我們對隊列有了一個初步的概念。那么,在Java中的隊列究竟如何實現(xiàn)呢?
1.1 隊列的兩種形式
在Java中,隊列分為2種形式,一種是單隊列,一種是循環(huán)隊列;
通常,都是使用數(shù)組來實現(xiàn)隊列,假定數(shù)組的長度為6,也就是隊列的長度為6;
- 來看單隊列情況:
第一步,創(chuàng)建一個空數(shù)組,有兩個變量,分別為front、rear,代表著頭指針、尾指針;
第二步,向隊列中插入數(shù)據(jù);
第三步,移除隊頭中的數(shù)據(jù);
第四步,再次向隊列中插數(shù)據(jù)(此時rear指針指向了一個不存在的角標);
此時,單隊列發(fā)生了“假溢出”情況,尾指針指向了一個不存在的數(shù)組角標。
如果,要解決該情況的發(fā)生,有兩種方式-----一,無限擴充數(shù)組大小;二,引入循環(huán)隊列;
- 來看循環(huán)隊列情況:
當尾指針超過了數(shù)組角標大小,此時我們會判斷隊列的頭部是否有剩余的空間,如果有就把尾指針指向隊列的頭部;
此時,循環(huán)隊列就產(chǎn)生了。
其實,循環(huán)隊列就是將單隊列的首位進行相連,形成了一個圓圈,這樣就不會發(fā)生角標越界的情況了(distruptor實現(xiàn));