Java HashSet vs Array Performance

我有一个对象的集合,这些对象保证是不同的(特别是,由唯一的整数ID索引)。我也确切地知道它们有多少个(并且数量不会改变),并且想知道Array在存储/检索所述元素方面是否比HashSet具有显着的性能优势。

在纸面上,Array保证恒定的时间插入(因为我提前知道大小)和检索,但是HashSet的代码看起来更干净,并增加了一些灵活性,所以我想知道我是否在性能方面丢失了任何东西,至少在理论上是这样。


答案 1

取决于您的数据;

HashSet为您提供了一个 contains() 方法,但不保留顺序。O(1)

ArrayListcontains() 是,但您可以控制条目的顺序。O(n)

Array如果您需要在两者之间插入任何内容,最坏的情况可能是O(n),因为您必须将数据向下移动并为插入腾出空间。在 中,您可以直接使用SetSortedSet which too has O(n) too but with flexible operations.

我相信Set更灵活。


答案 2

选择很大程度上取决于你想用它做什么。

如果这是您的问题中提到的内容:

我有一个对象的集合,这些对象保证是不同的(特别是,由唯一的整数ID索引)。我也确切地知道他们中有多少人

如果这是你需要做的,你既不需要它们。在 Collection 中有一个 size() 方法,你可以获取它的大小,这意味着集合中有多少个。

如果你所说的“对象集合”并不是真正的集合,并且需要选择一种集合类型来存储你的对象以供进一步处理,那么你需要知道,对于不同类型的集合,有不同的功能和特征。

首先,我认为要进行公平的比较,您应该考虑使用ArrayList而不是Array,为此您不需要处理重新分配。

然后它成为ArrayList与HashSet的选择,这是非常直截了当的:

您需要列表或集合吗?它们用于不同的目的:列表为您提供索引访问,迭代按索引顺序排列。虽然 Sets 主要用于保留一组不同的数据,但鉴于其性质,您将没有索引访问权限。

在您决定使用列表或集合后,可以选择列表/集合实现,通常对于列表,您可以从ArrayList和LinkedList中进行选择,而对于Set,您可以在HashSet和TreeSet之间进行选择。

所有选择都取决于您要对该数据集合执行的操作。它们在不同的动作上表现不同。

例如,ArrayList中的索引访问是O(1),在HashSet中(尽管没有意义)是O(n),(只是为了您的兴趣,在LinkedList中是O(n),在TreeSet中是O(nlogn))

为了添加新元素,ArrayList和HashSet都是O(1)操作。在中间插入是 ArrayList 的 O(n),而在 HashSet 中没有意义。两者都将遭受重新分配的影响,并且它们都需要O(n)进行重新分配(HashSet在重新分配时通常较慢,因为它再次涉及每个元素的哈希计算)。

要查找集合中是否存在某些元素,ArrayList 为 O(n),HashSet 为 O(1)。

您仍然可以执行许多操作,因此在不知道要执行的操作的情况下讨论性能是毫无意义的。