我有一组保证不同的对象(特别是由唯一的整数ID索引)。我也确切地知道它们中有多少(并且数字不会改变),并且想知道Array是否会比HashSet具有显着的性能优势来存储/检索所述元素。
在纸面上,Array保证了恒定的时间插入(因为我提前知道了大小)和检索,但是HashSet的代码看起来更清晰并且增加了一些灵活性,所以我想知道我是否会失去任何性能 - 至少在理论上使用它是明智的。
答案 0 :(得分:21)
取决于您的数据;
HashSet
为您提供O(1)
contains()方法但不保留顺序。
ArrayList
contains()是O(n)
,但您可以控制条目的顺序。
Array
如果您需要在两者之间插入任何内容,最坏的情况可能是O(n),因为您必须向下移动数据并为插入腾出空间。在Set
中,您可以直接使用SortedSet which too has O(n) too but with flexible operations.
我相信Set更灵活。
答案 1 :(得分:2)
对于企业软件可扩展,可维护和清洁代码要好得多。所以我选择HashSet。
答案 2 :(得分:1)
选择很大程度上取决于你想用它做什么。
如果是你问题中提到的内容:
我有一个集合的对象保证是不同的(特别是,由唯一的整数ID索引)。我也确切地知道有多少
如果这是你需要做的,你就不需要它们。 集合中有一个size()方法,您可以获取它的大小,这意味着集合中有多少。
如果您对“对象集合”的意思不是真正的集合,并且您需要选择一种集合来存储您的对象以进行进一步处理,那么您需要知道,对于不同类型的集合,有不同的能力和特点。
首先,我认为有一个公平的比较,你应该考虑使用ArrayList而不是Array,你不需要处理重新分配。
然后它成为ArrayList vs HashSet的选择,这非常简单:
你需要一个List还是Set?它们用于不同的目的:列表为您提供索引访问,迭代按索引顺序。虽然集合主要是为了保存一组不同的数据,但鉴于其性质,您将不会拥有索引访问权。
在您决定使用List或Set之后,它是List / Set实现的选择,通常对于Lists,您从ArrayList和LinkedList中选择,而对于Sets,您可以在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)。
你仍然可以做很多操作,所以在不知道你想做什么的情况下讨论性能是毫无意义的。
答案 3 :(得分:0)
理论上,正如SCJP6学习指南所说:D
数组比集合更快,如上所述,大多数集合主要依赖于数组(地图不被视为集合,但它们包含在集合框架中)
如果你保证元素的大小不会改变,为什么会陷入对象构建的对象(构建在数组上的集合),而你可以直接使用根对象(数组)
答案 4 :(得分:0)
看起来你会想要一个将id's映射到计数的HashMap。特别是,
HashMap<Integer,Integer> counts=new HashMap<Integer,Integer>();
counts.put(uniqueID,counts.get(uniqueID)+1);
通过这种方式,您可以分摊O(1)添加,包含和检索。本质上,具有与每个对象关联的唯一id的数组是HashMap。通过使用HashMap,您可以获得额外的好处,即无需管理数组的大小,无需自己将键映射到数组索引和持续访问时间。