2012-03-05 117 views
1

考慮具有以下結構的巨大CSV(改性爲簡單起見):爪哇:同鍵映射的地圖

ID, NAME, ADDRESS, PHONE, MAIL 
1, Jon, UK,  403, [email protected] 
2, Marc, UK,  292, [email protected] 
3, Darin, France, 291, [email protected] 
... 
(Some million records) 

爲快速獲取的自然數據結構是散列表,其中每ID是一個關鍵和NAME, ADDRESS, PHONE, MAIL是價值。我的dillema是價值觀的數據結構。

將它存儲在一個HashMap,其中每個行標題是關鍵是浪費空間,因爲每行的行標題完全相同。把它作爲一個數組將失去每個項目的元數據,因爲讀者

我想的是兩種方法:

  • 超載Java的HashMap中。行標題將被存儲一次,並且每個ID都將與一個字符串數組關聯。 get()方法將被重載,以便它將返回標題行和行中相應字段之間的映射。

  • 創建一個啞類存儲使用getter和setter每一行的數據(row.getMail()row.getAddress(),...)

什麼是正確的方式去,在存儲效率方面,類型安全和速度?

回答

2

我會去「啞」類而不是重載集合。

我不知道類型的安全性或速度,但我會說你的代碼會更具可讀性。這些價值觀聚在一起;將它們封裝在一個對象中以強調這一點。除了get/set之外,還有與他們有關的行爲嗎?如果是的話,那麼更好。

1

我不會擔心浪費的空間,除非你知道你有問題。即您有很多GB的數據。

如果您想知道更高效的方法,您可以使用Map<String, Integer>的組合來查找密鑰,併爲每行使用Object[]。要按名稱查找,您首先需要查找該號碼。

更高效的方法是按列而不是按行存儲數據。因爲你往往比

Map<String, List> columns = ... 

更行可以按名稱,然後再查找由小區列表中的條目這是更有效的。如果您想使用原始類型,則可以使用int[]double[]TIntArrayListTDoubleArrayList來節省內存。 ADDRESS國家可能是枚舉類型。

除非你有數百萬行,否則我會保持簡單。

+0

我確實有幾百萬條記錄。 – 2012-03-05 11:39:56

+0

在這種情況下,可能值得測試它是否足夠重要(小於我不會打擾)。您仍然可以發現,雖然它節省了100 MB,但這隻會意味着您的服務器的可用內存增加了100 MB,但保持代碼更簡單實際上是一個更好的主意。 – 2012-03-05 12:19:24

+0

我會考慮這個 - 謝謝! – 2012-03-05 12:34:47

2

雖然'啞'類是更清潔的方法,但它明顯不如地圖方法的通用,並且需要解析CSV格式的特定邏輯 - 所以這是一個折衷。

什麼是可能較少的折衷是您對內存效率的擔心 - 字符串是interned,因此每個行映射實際上都具有相同的字符串實例,因此開銷將只下降到引用每個字符串。