2012-03-05 76 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,因此每个行映射实际上都具有相同的字符串实例,因此开销将只下降到引用每个字符串。