2012-02-21 69 views
1

我的問題的基礎是在Java中給出了List對象,返回唯一數據集合的最快方法是什麼?收集Java列表中唯一數據的最快方法

更具體的版本是,我有一個2d ArrayList(想象它像一個表),我想循環給定的列索引並返回唯一的數據。

這裏是我的當前設置:

public Set<Object> getDistinctColumnData(int colIndex) { 

    //dataByIndex = List<List<Object>> 

    Set<Object> colDistinctData = new HashSet<Object>(dataByIndex.size() + 1, 1f) ; 

    for(List<Object> row : dataByIndex) { 
     colDistinctData.add(row.get(colIndex)) ; 
    } 

    return colDistinctData ; 

} 

我有一個小的性能增益,當我最初的容量設置爲加一個非組不同的大小和負載因子1(我的想法是它贏得直到它達到100%才需要增長,即使原始設置已經100%截然不同(或者我錯了嗎?))。

有沒有更快的方法?

+0

downvoter會照顧一個理由嗎? – CrazyPenguin 2012-02-21 19:59:45

+0

我會使用'(dataByIndex.size()* 3/2)'作爲初始大小,並保留負載因子,除非您預計會有大量重複項。 – 2012-02-21 20:02:46

+1

你的代碼看起來不錯。處理別的事情。 – Bohemian 2012-02-21 20:09:17

回答

0

我認爲如果你只有兩個獨特的集合,它會更快。維護你的dataByIndex列表,還維護一個dataSet集合(Set)。當你插入到你的dataByIndex列表中時,也放入你的dataSet集合中。然後在需要的地方使用你的dataSet。 Set將會保持Set的本質唯一性。

+0

我想過這個。將處理移至添加行的時間。但是增加數據的性能損失(發生這種情況比獲取不同數據更頻繁)並不是真正值得獲取不同數據的收益。 – CrazyPenguin 2012-02-21 20:06:12

+0

你有基準差異嗎?這應該是一個相對簡單的代碼更改,我認爲你可能會對這種影響感到驚訝... – Shinzul 2012-02-21 20:08:33

+0

如果OP說插入比獨立查詢發生得更多(這是不尋常的,但我們沒有理由懷疑它),那麼確實保持一個單獨的獨立集可能會達到性能而不是改善它。 – biziclop 2012-02-21 20:26:23

0

我認爲將容量和負載係數設置爲您指定的值沒有多大意義。你使用什麼散列函數?可能是降級到鏈接列表?

0

如果增加HashSet的初始容量,您可能會進一步提高性能(平均)。這是因爲您的列表中對象的散列值的分佈可能會導致碰撞更可能發生。

例如,給定以下列表,除第一次插入外,除第一次插入之外的所有插入都將導致衝突,儘管沒有重複的值。 (整數的Java哈希函數是整數本身的值,並且HashSet在發生衝突時使用開放尋址和線性探測)。

[0,10,1,2,3,4,5,6,7] 

甚至更​​糟,因爲每個插入必須檢查每個非空閒空間才能插入。

[0, 5, 25, 125] 

在最後一個例子0投入指數0.5得到去索引0最初5%的大小(即5)等於0,所以後來去索引1 125會去索引0,但是0在索引0處,5在索引1處並且25在索引2處。這意味着在三次檢查之後最終可以在索引3處插入125.

如果增加初始容量,則這降低了碰撞概率平均),並且如果發生碰撞,平均也會減少所需的檢查次數。默認情況下,java使用0.75的加載因子作爲性能和內存使用率之間的良好平衡。因此,除以0.75的負載係數,並加1應該給你一個很好的初始容量。

相關問題