在我用無意義的重言式殺死你之前,這是要點
- 如果您的應用程序接近實時,或者將代碼發送到Mars,則需要保留Java中默認的Stack實現。 根據
LinkedList
編寫您自己的版本。 - 同樣,如果您的應用程序是關鍵任務,并且希望堆棧由并發線程處理,則使用
ConcurrentLinkedDeque
或基于LinkedList
編寫自己的Stack
-只需確保添加和刪除操作是線程安全的即可。 這樣做時,請考慮并發鎖 。 - 您只需要原始電源,并且在
push
過程中不會被偶爾的打擾所困擾,并且您的Stack
不會被并發線程操縱,然后使用ArrayDeque
或繼續基于ArrayList
編寫自己的Stack。 - 如果是多線程的,則根據
ArrayQueue
和util.concurrent鎖編寫自己的Stack
。 - 如果您拒絕閱讀Java Stack API和Java Deque API,而您只是個瘋子,那么請使用默認實現。 而且,我保證,當機器人占領世界時,不會顯示憐憫之心。
注意:事實是,除非出于某種原因,您想要將實現類命名為' Stack ',否則您可以自由地將所有Deque實現直接用作Stack。
既然已經對默認實現拋出了足夠多的麻煩,請注意幾分鐘,讓我快速總結一下。
我們知道Java Collection API中的Stack
是從Vector
內部擴展的, Vector
在內部使用數組。 換句話說,Java將基于數組的實現用于其Stack
。
因此,讓我們看看為什么在兩個最受歡迎的Stack
實現之間-數組和鏈表,Java選擇了數組。
有些答案很明顯,有些則沒有:
公平競爭
粗略地看一下數組和鏈表的add
和remove
方法(它們是Stack
的push
和pop
方法的Struts),可以在整個板上進行恒定時間的檢索。
增長問題
數組是固定大小的,并且僅通過將數組復制到更大的數組即??可實現數組的增長 ,這并不是什么新聞。 在我們默認使用Vector實現Stack的情況下,增量容量僅為兩倍。
這只是意味著,如果我們要向堆棧中添加80個元素,則內部數組將被復制4次–分別為10、20、40和80。因此,也就是說,當我們添加第80個元素時,push操作實際上需要O(N )時間,因為在這種情況下,我們的N為80,所以使用該殘酷的深層副本將使您的程序至少稍稍停頓一下–您可以節省其他寶貴時間的寶貴小循環。
遺憾的是,與Vectors不同,您將無法指定java.util.Stack
的初始大小或增量因子,因為沒有重載的構造函數。
另一方面,盡管增長經常會ArrayQueue
,但ArrayQueues的初始容量有一個甜美的重載構造函數,如果您對堆棧的大小有一個大概的了解,這將派上用場。 此外,默認初始容量是16用于ArrayQueue
用于作為對10 Vector
。
時間和地點,我的朋友。 時間和地點
為了與數組公平,存儲在基于數組的堆棧中的對象只是對堆中實際對象(對于對象而言)或實際值(對于基元而言)的引用。
另一方面,在LinkedList的情況下,存儲項目的頂部上方有一個Node
包裝器。 平均而言,每個存儲的對象(包括Node對象的內部類,鏈接到下一個Node以及對項本身的引用)將在堆中花費約40字節的額外空間。
那么,ArrayQueue或LinkedList嗎?
數組在大多數情況下都是首選的,因為它們具有占用順序存儲器的獨特優勢,并且它們提供了更快的訪問速度,而到達實際對象只是指針運算。 但是,對閾值項目(觸發調整大小的項目)的push
和pop
操作需要O(n)
時間。 但是,平均而言,它需要花費固定時間(如果需要,可以攤銷固定時間)。
另一方面,使用LinkedList
,由于要花費更多的時間來構造新節點并指向新節點,所以add
操作比數組要慢。 不用說,新節點消耗的堆空間不是實際對象消耗的空間。 但是,由于沒有大小調整(或需要順序存儲),并且總是引用第一個元素,因此最壞的情況是保證了恒定的時間。
現在,當您重新訪問本博客的第一部分時,請隨意說該死,默認實現!!!
相關鏈接 :
- http://onjava.com/pub/a/onjava/2001/10/23/optimization.html
- http://www.javaworld.com/javatips/jw-javatip130.html?page=1
- http://docs.oracle.com/javase/7/docs/api/java/util/RandomAccess.html
- http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Vector.java
參考資料: 為什么我們的JCG合作伙伴 Arun Manivannan會使用Rerun.me博客中的后代 人 討厭使用java.util.Stack 。
翻譯自: https://www.javacodegeeks.com/2012/11/why-future-generations-will-hate-you-for-using-java-util-stack.html