2009-05-22 64 views
5

我通常總是發現使用標題中列出的接口的具體類就足夠了。通常,當我使用其他類型(如LinkedList或TreeSet)時,原因是功能而不是性能 - 例如,隊列的LinkedList。Java:ListList的ArrayList,Map的HashMap和Set的HashSet?

我的確有時候構造的ArrayList的初始容量超過了默認的10,而HashMap的容量超過了默認桶16,但我通常(特別是對於商業CRUD)並沒有看到自己在想「嗯......應該如果我只是插入並遍歷整個List,我使用LinkedList來代替ArrayList?「

我只是想知道其他人都在這裏使用(爲什麼)和什麼類型的,他們開發應用程序。

回答

10

這些肯定是我的默認設置,儘管LinkedList實際上通常是列表的最佳選擇,因爲絕大多數列表似乎只是按順序迭代,或者無論如何都通過Arrays.asList轉換爲數組。

但是在保持一致的可維護代碼方面,標準化這些代碼並使用替代品是有道理的,這樣當有人讀取代碼並看到替代代碼時,他們立即開始認爲代碼做了一些特殊的事情。

我總是輸入參數和變量作爲集合,地圖和列表,除非我有特殊的理由來引用子類型,這種切換方式當你需要時是一行代碼。

我可以看到有時明確要求一個ArrayList,如果你需要的隨機訪問,但在實踐中真的不會發生。

+3

即使你只是重複,一個ArrayList通常是更好的,因爲它有較少的內存開銷。 – 2009-05-22 11:18:59

+2

+1始終總是使用接口類,除非你有充分的理由。我通過將使用List(由ArrayList支持)的實現轉換爲CopyOnWriteArrayList來解決了真正的世界問題。一行修復。始終使用接口。 – basszero 2009-05-22 11:27:08

+0

@邁克爾,好點,但在我的寫作中沒有說明的是,添加到列表並不知道它的大小比拉取特定編號的元素更常見。但是我仍然默認使用ArrayList。 – Yishai 2009-05-22 13:10:27

1

剛剛出來一個關於數據結構性能等級的,我通常會看那種算法我正在開發或結構的目的之前,我選擇的實現。

例如,如果我要建,有很多隨機訪問到它的清單,我會因爲它的隨機存取性能還是不錯的使用ArrayList,但如果我的東西插入到列表中了很多,我可能會選擇一個LinkedList。 (我知道現代實現可以消除很多性能障礙,但是這是想到的第一個例子。)

您可能想要查看某些維基百科頁面的數據結構(尤其是那些處理sorting algorithms,其中性能尤其重要)以獲得更多關於性能的信息,以及關於測量數據結構上各種功能性能的一般性討論的文章。

2

是的,我使用這些作爲默認值。我通常有一個關於公共類方法的規則,我總是返回接口類型(即Map,Set,List等),因爲其他類(通常)不需要知道具體具體類是什麼。在類方法內部,只有當我需要訪問它可能具有的任何額外方法(或者使它更容易理解代碼)時才使用具體類型,否則將使用該接口。

雖然隨着時間的推移(特別是隨着代碼變得更加複雜),具體類可見性的依賴性會隨着時間的推移而變化,但使用您所使用的任何規則都很靈活。

0

我傾向於使用一個*隊列班隊列。然而,如果你不需要線程安全,LinkedList是一個不錯的選擇。

3

對於某些列表(例如,聽衆),使用CopyOnWriteArrayList而不是普通的ArrayList是有意義的。對於幾乎所有其他的東西,您提到的基本實現都已足夠

0

使用接口類型(List, Map)而不是實現類型(ArrayList, HashMap)在方法中是無關緊要的 - 它在公共API中非常重要,即方法簽名(和「public」不一定意味着「打算在外部發布你的團隊)。

當一個方法接受一個ArrayList作爲參數,你有別的東西,你就完蛋了,不得不白白複製您的數據。如果參數類型是List,來電者是更加靈活,可以如使用Collections.EMPTY_LISTCollections.singletonList()

2

事實上,送花兒給人s使用基本接口Collection,List,Map來代替它們的實現。爲了使thinkgs更加靈活,你可以躲在後面靜態工廠方法的實現,它允許你切換到的情況下,不同的實現你找到更好的東西(我懷疑會有在這一領域的巨大變化,但你永遠不知道)。另一個好處是,由於泛型,語法更短。

Map<String, LongObjectClasName> map = CollectionUtils.newMap(); 

instead of 

Map<String, LongObjectClasName> map = new HashMap<String, LongObjectClasName>(); 


public class CollectionUtils { 
..... 

public <T> List<T> newList() { 
     return new ArrayList<T>(); 
    } 

    public <T> List<T> newList(int initialCapacity) { 
     return new ArrayList<T>(initialCapacity); 
    } 

    public <T> List<T> newSynchronizedList() { 
     return new Vector<T>(); 
    } 

    public <T> List<T> newConcurrentList() { 
     return new CopyOnWriteArrayList<T>(); 
    } 

    public <T> List<T> newSynchronizedList(int initialCapacity) { 
     return new Vector<T>(initialCapacity); 
    } 

... 
} 
1

我真的不有一個「默認」,但我想我使用的問題往往不是列出的實現。我想想適合我正在工作的任何特定問題,並使用它。我不只是一味地默認使用ArrayList,我把想法30秒沿「好,我會做很多迭代並在此列表中的中間刪除元素,所以我應該使用的線LinkedList「。

而且我幾乎總是使用的接口類型供我參考,而不是執行。請記住List不是LinkedList實現的唯一接口。我看到這個有很多:

LinkedList<Item> queue = new LinkedList<Item>(); 

當什麼程序員意思是:

Queue<Item> queue = new LinkedList<Item>(); 

我也用Iterable接口相當數量。

1

如果使用鏈表的隊列,你可能會考慮使用雙端隊列接口和ArrayDeque實現類(在Java 6中引入)代替。引述的Javadoc ArrayDeque:作爲堆疊使用時,作爲一個隊列使用時比鏈表更快

這個類是可能比 堆棧更快。

0

我也一般使用ArrayList,但是我會根據具體情況使用TreeSet或HashSet。然而,在編寫測試時,Arrays.asList和Collections.singletonList也經常使用。我一直在編寫線程本地代碼,但我也可以看到使用各種併發類。

而且,有很多次我用的ArrayList,當我真正想要的是一個LinkedHashSet(它是可用之前)。