2011-04-27 31 views
2

我發現了一個有效的代碼添加使用下面的方法獨特的項目:爲什麼我們在使用Set來添加唯一值時使用ArrayList?

int[] values = { -5, -3, -1, 0, 3, 6 }; 

List<Integer> list=new ArrayList<Integer>(); 

for(int val : values) 

{ 

    if(!list.contains(val)) 

    list.add(val); 

} 

我可以用一個HashSet,而不是使用一個ArrayList也做了同樣的工作。這會幫助我,不用擔心檢查列表中是否存在價值。爲什麼使用Hashset不是一種有效的方法?

+2

一個'List'從來沒有被滿足/被設計爲保存唯一值,所以我沒有看到你的問題的重點。如果你想保持獨特的價值,只需繼續'Set'。爲此目的使用正確的數據結構。 – BalusC 2011-04-27 04:23:44

+1

一個ArrayList可以保持唯一的值就好,它不能確保唯一性。對於按位置查找而言,它比'contains'更好(它必須掃描列表)。我們需要更多關於他想實現的內容的背景。 – Thilo 2011-04-27 04:26:14

回答

4

一個HashSet沒有實現List接口。並且Set中的值未編入索引。我們不能得到價值從Set

因此,如果您只需要存儲唯一值,那麼您可以安全地使用Set實現。如果您需要保留廣告訂單或需要List實現唯一性的任何其他功能,請使用您的問題的方法:裝飾現有的List實現並添加拒絕重複的功能。

您問到效率:ArrayList由一個數組支持,速度非常快。但是的時間複雜度是O(n) - 迭代我們看最壞情況下的每一個元素。

HashSet或多或少是一個完整的HashMap的裝飾,比array稍重。但是contains的時間複雜度爲O(1) - 無論在地圖內有多少物品,檢查都是在一定的時間內完成的。

如果你只是想迭代 - 一個專門的List實現應該稍微快一點 - 兩個迭代的時間複雜度爲O(n)(沒有什麼意外),但是從一個Map讀取數組更容易。

+0

非常感謝你這麼可愛的回答。也非常感謝其他朋友爲了給他們的時間。我想我應該讀更多關於計算循環的時間複雜度。 @再次感謝。問候,克里希納 – 2011-04-27 06:17:44

3

實際上,HashSet很多ArrayList更好的方法。您的代碼在O(n)中運行HashSet,O(n2)爲ArrayList

但是,請記住一點:HashSet中的元素沒有按任何特定順序保存。如果您想保持訂單的快速查找,請使用LinkedHashSet。 (儘管如此,一切都有成本;在這種情況下,LinkedHashSet使用的內存量大於HashSet。)

+0

但是,至少在這個例子中'n'非常小。無論如何,元素是不同的。爲什麼在使用原始數組時可以使用List?沒有更多的背景,這裏很難給出建議。 – Thilo 2011-04-27 04:22:02

+0

@Thilo:這是真的,需要更多的上下文。 – 2011-04-27 04:23:32

+1

感謝您的建議。我想計算數組中的唯一值。我想到給elist添加uniuqe值,然後獲得列表的大小以獲得唯一值的數量。但現在閱讀你的答案後,我覺得我應該使用HashSet,然後將值添加到它,然後獲得大小。謝謝:) – 2011-04-27 04:42:10

1

這是。你的問題的前提是有缺陷的。

使用guava和更容易:

Set set = Sets.newTreeSet(values); //或HashSet的

+1

如果你使用番石榴,我寧願使用'ImmutableSet.of(-5,-3,-1,0,3,6)'代替。不變性FTW。 :-) – 2011-04-27 04:22:50

+0

哈哈,夠公平的。我認爲'values'沒有實際定義,否則Arrays.asList()可能已經構建了數組列表,並且不需要檢查重複數據。 ;) – 2011-04-27 04:23:48

+0

好的。如何:'ImmutableSet.copyOf(values)'。仍然是一套,仍然是不變的。 :-) – 2011-04-27 04:25:35

相關問題