如何在Java中加载海量数据文件?任何比哈希表更好的结构?

时间:2012-10-28 02:24:51

标签: java file data-structures hashtable

我正在尝试在内存中加载一个包含1400万行哈希表的大文件。每行包含三个数字(n,m,v),其中:

  • n:是用户(对象)的id
  • m:是项目(对象)的id
  • v:是用户n给项目m的费率。

每个用户n都有一个hashtable<item, rate>来存储用户评分的项目, 并且每个项目都有一个hashtable<user, rate>来存储评价此项目的用户。

在我的机器上,我无法将此结构加载到内存中,因此每次都会出现堆内存错误。

我尝试用hashBasedTable替换hashtables,它允许每个值的两个键,但没有解决方案。另外hashBasedTable让我的程序慢得多。

是否有任何解决方案可以加载大量数据?

4 个答案:

答案 0 :(得分:2)

每三千万行三个数字听起来不像一个海量数据阵列。 大约是14M *(3 + 1)* 8~450M或记忆。

只需确保将-Xmx设置为足够大的值(例如-Xmx1024m - 这将允许JVM分配最多1G的RAM)。

P.S。我会建议HashMap而不是HashTable

答案 1 :(得分:1)

我建议您分别使用ArrayList<User>ArrayList<Item>代表每个评分项目的用户和每个用户的评分项目。这将节省大量空间。

不可否认,某些操作现在为O(N),但如果N变大,则只会出现问题。 (如果确实如此,请考虑混合使用ArrayList表示小关系,HashMap表示大关系。)

建议#2 - 使用普通数组...并对它们进行排序,以便您可以使用二进制搜索实现查找。这是代码密集型(即更复杂),但它会比使用Collection类型更好地使用内存。

建议#3 - 使用数据库。它会更好地扩展。

答案 2 :(得分:0)

我认为这取决于您使用的数据结构。你根本无法将如此多的数据加载到RAM中,你必须逐行处理文件并执行你拥有的逻辑。

答案 3 :(得分:0)

我对你的访问模式有点不清楚,但听起来你可能想要使用一个大表而不是每个用户和每个项目一个。特别是如果您的数据非常稀疏(每个用户只有少数项目,反之亦然),由于哈希表的初始容量,您将浪费大量空间(您可以尝试降低初始容量和/或提高加载因子)如果你想保留现有的组织。)

构建一个pair对象(用户id,item id),用作单个大哈希表的键。如果您需要枚举(即列出用户的所有项目,反之亦然),请保留该数据的ArrayList并使用trimToSize,比哈希表更紧凑。