2013-01-20 34 views
7

Queue在Java中提供了FIFO數據結構。根據我所瞭解到的情況,排隊有責任堅持先進先出的行爲。換句話說,您不可以從隊列中移除項目。但是,在Java中,我們可以使用iterator來刪除隨機隊列元素。Java中的隊列允許刪除隨機元素。這是不好的?

這是一個糟糕的設計封裝嗎?或者是應該允許這個的隊列數據結構?

Queue<String> queue = new LinkedList<String>(); 
queue.add("e1"); 
queue.add("e2"); 
queue.add("e3"); 
queue.add("e4"); 

queue.remove("e3"); 
+4

從文檔:「_Queues通常但不一定,在FIFO之中的異常(先入先出)方式順序元件是優先級隊列,根據所供給的COMPAR何種順序元件。 ator或元素的自然排序,以及排序元素LIFO(後進先出)....的LIFO隊列(或堆棧)....「更多閱讀[here] com/javase/6/docs/api/java/util/Queue.html) – jahroy

+0

我認爲這是爲了強調優先級隊列和這些實現的行爲。 –

+0

來自'Queue extends Collection'。無論是那個還是'​​UnsupportedOperationException',我都恨平等。從嚴格的'C++''LSP'轉換到'Java'時,這是一個很大的驚喜。 –

回答

6

Queue明顯是通過在Collection層次結構的一部分繼承了一些這方面的附加功能。從多態的角度來看,使Queue像任何其他Collection一樣起作用是有益的,因爲它增加了數據結構的可移植性。

從設計的角度來看,我不會說這是不好的。想象一下在一家雜貨店的排隊/排隊。在某些情況下,客戶可能需要從線路中間移除。隊列的這個特定的實現支持這個,這可能是有用的。

雖然你可能會認爲,額外的方法可以讓你拍攝自己的腳,你可以很容易地創建Queue的實現,不允許像remove(Object)iterator.remove()的事情,如果你想要一個嚴格Queue

3

每我學到了什麼,隊列有一定的責任,要堅持先入先出的行爲。

您可能一直在閱讀教科書或某些講義或描述理想化的FIFO隊列如何工作的內容。但是你沒有意識到的是,並不是所有的隊列是FIFO。不在現實世界中,也不在計算機系統中。 (例如,如果(假設)奧巴馬總統去了一家忙碌的麥當勞餐廳,你會發現他立即被移到隊列的前端,這是一個非FIFO隊列行爲。)

反正,Java Queue是任何類型的隊列的接口,而不僅僅是FIFO隊列。它還支持優先級隊列以及任何其他您可能想到的排隊語義......如果您關心提供您自己的實現類。

另一點是remove(E)操作不提供「下一個客戶請」操作。這相當於一個顧客決定他們真的更喜歡披薩......並走出了門外。理想化的隊列不支持這一點,但可用的庫類可以......因爲應用程序需要能夠做到這一點。

底線是Java Collection類層次結構(包括線索Queue)的設計是有用的,易於使用的,而不是硬性適應數據結構的人的抽象模型。


但是後來排隊可允許偷偷溜方法,可以讓你在潛行到隊列的中間 - 這裏是方法?

那麼,因爲大多數真正的應用程序不需要它,它不在那裏。 (如果這是一個常見的用例,將提供這樣的方法,即使不是在Queue接口特定隊列實現類。)

再次,Java類和接口都爲他們的實用性和易用性規定真正的節目,而不是(在這種情況下),所以他們可以在漢堡聯合模型POTUS。

也許我被書本定義和C/C++實驗室的腦沖走了,我在學校做過。

另一種解釋是你誤以爲定義的真正目的等等。

+0

是的,我曾想過類似的例子。但是'Queue'可能會允許一個'sneakIn'方法,它可以讓你潛入隊列的中間 - 該方法在哪裏?也許我被書中的定義和我在學校做過的C/C++實驗室洗腦。 –

1

Java隊列不一定是FIFO。隊列API說

Queues typically, but do not necessarily, order elements in a FIFO (first-in-first-out) manner

它取決於實現,例如PriorityQueue不是FIFO,而是您使用的LinkedList是FIFO。

Queue.remove()API並不表示它刪除隨機元素,它說

Retrieves and removes the head of this queue. 

在你的榜樣它必須

queue.remove(); 

,它會刪除e1

+0

是的,但是重載的'remove'可以讓你從隊列中間移除物品,這與我最不感到驚訝的原則相違背。 –

+0

好吧,但是這會破壞Queue.remove合同,它說「刪除隊列頭」 –