我应该为一个非常大的数据集使用`HashSet`或`TreeSet`吗?

我需要在数据结构中存储2到1,500万个帐户(长度为15的String ),以便查找和检查唯一性。 最初我计划将它们存储在HashSet ,但是我怀疑由于哈希冲突导致查找的速度会很慢,并且最终会比TreeMap慢(使用二进制搜索)。

不需要对数据进行排序。 我正在使用Java 7.我有64G系统,48G专用于此应用程序。

这个问题不是HashSet和TreeSet性能测试的重复,因为该问题是关于Set添加元素的性能,这个问题是关于检查现有Set的重复值的性能。

如果您有200万到1500万条记录的48 GB专用内存,最好的办法是使用HashMap ,其中您的密钥是IntegerString具体取决于您的要求。

只要您为Map提供足够的内存并具有适当的加载因子,就可以完成哈希冲突。

我建议使用以下构造函数: new HashMap<>(13_000_000); (比预期的记录数量多30% – 这将通过HashMap的实现自动扩展到2^24单元格)。 告诉你的应用程序,这个Map从一开始就会非常大,因此它不需要在填充时自动增长。

HashMap使用O(1)访问时间,而TreeMap使用O(log n)查找时间,但对内存更有效,并且不需要聪明的散列函数。 但是,如果您使用的是StringInteger键,则无需担心设计散列函数,并且常量时间查找将是一个巨大的改进。 另外, TreeMap / TreeSet另一个优点是排序顺序,你说你不关心它; 使用HashMap

如果列表的唯一目的是检查唯一帐号 ,那么我上面说过的所有内容仍然是正确的,但正如您在问题中所述,您应该使用HashSet ,而不是HashMap 。 性能建议和构造函数参数仍然适用。

进一步阅读: HashSet和TreeSet性能测试

当我们尝试使用适当的初始化参数在HashMap中存储5000万条记录时,插入开始减速,特别是在3500万条记录之后。 更改为TreeMap提供了持续的插入和检索性能。

观察:对于大型输入集,TreeMap将提供比HashMap更好的性能。 对于较小的集合,HashMap当然会提供更好的性能。