迭代遍历TreeSet比迭代Java中的HashSet要慢吗?

时间:2013-11-05 20:31:39

标签: java iteration hashset treeset

我正在运行一些基准测试。我的一个测试取决于顺序,所以我正在使用TreeSet。我的第二个测试没有,所以我正在使用HashSet。

我知道TreeSet的插入速度较慢。但是如何迭代所有元素呢?

3 个答案:

答案 0 :(得分:1)

来自类似的帖子(Hashset vs Treeset):

HashSet比TreeSet快得多(对于大多数操作,例如add,remove和contains,常量时间与日志时间相比),但不提供像TreeSet这样的排序保证。

HashSet的:

  • class为基本操作(添加,删除,包含和大小)提供恒定的时间性能。
  • 不保证元素的顺序会随时间保持不变
  • 迭代性能取决于HashSet的初始容量加载因子
    • 接受默认加载因子是非常安全的,但您可能希望指定的初始容量大约是您希望该组增长的大小的两倍。

TreeSet中:

  • 保证基本操作(添加,删除和包含)的日志(n)时间成本
  • 保证set的元素将被排序(升序,自然,或者你通过它的构造函数指定的元素)
  • 不提供迭代性能的任何调整参数
  • 提供了一些方便的方法来处理有序集合,例如first()last()headSet()tailSet()

要点:

  • 两者都保证元素的无重复收集
  • 将元素添加到HashSet然后将集合转换为TreeSet以进行无重复的排序遍历通常会更快。
  • 这些实现都不是同步的。也就是说,如果多个线程同时访问集合,并且至少有一个线程修改了集合,则必须在外部进行同步。
  • LinkedHashSet 在某种意义上介于HashSetTreeSet之间。实现为具有贯穿其的链表的哈希表,但它提供插入顺序迭代,这与TreeSet保证的排序遍历不同。

因此,使用的选择完全取决于您的需求,但我觉得即使您需要有序集合,您仍然应该更喜欢HashSet来创建Set,然后将其转换为TreeSet。

  • e.g。 Set<String> s = new TreeSet<String>(hashSet);

答案 1 :(得分:1)

TreeSets内部使用TreeMaps Red Black Trees(特殊类型的BST)。

BST Inorder遍历为O(n)

HashSets内部使用HashMaps使用array来保存Entry对象。

此处遍历也应为O(n)

除非你写一个基准,否则很难证明哪个更快。

答案 2 :(得分:0)

如果您想要(几乎)HashSet的性能稳定排序,请使用LinkedHashSet。你仍然会得到恒定时间的操作,而我会假设TreeSet会得到你的对数时间。