默认收集类型

时间:2010-08-18 08:25:14

标签: java collections

假设您需要在Collection中存储/检索项目,不关心排序,并且允许重复,您使用的是什么类型的Collection

默认情况下,我总是使用ArrayList,但我记得在某处读取/听到Queue实施可能是更好的选择。 List允许在任意位置添加/检索/删除项目,这会导致性能损失。由于Queue不提供此功能,因此在不需要此功能时理论上应该更快。

我意识到所有关于性能的讨论都毫无意义,唯一真正重要的是测量。不过,我很想知道其他人在Collection使用什么时,他们不关心订购,允许重复,以及为什么

6 个答案:

答案 0 :(得分:8)

“这取决于”。你真正需要首先回答的问题是“我想把这个集合用于什么?”

如果您经常在其中一端(开头,结尾)插入/删除项目,Queue将优于ArrayList。但是,在许多情况下,您只需从中读取即可创建一个Collection。在这种情况下,ArrayList效率更高:因为它是作为一个数组实现的,你可以非常有效地迭代它(同样适用于LinkedList)。但是,LinkedList使用引用将单个项目链接在一起。因此,如果您不需要随机删除项目(在中间),ArrayList更好:ArrayList将使用更少的内存,因为项目不需要存储空间来引用下一个项目/ prev item。

总结一下:

ArrayList =如果您插入一次并经常阅读(随机访问或顺序)

,那就太好了

LinkedList =如果您经常在随机位置插入/删除并且只读顺序

,那就太好了

ArrayDeque(仅限java6)=如果您在开始/结束时插入/删除并随机或顺序读取

答案 1 :(得分:1)

默认情况下,我倾向于选择LinkedListArrayList。显然,我不是通过List接口使用它们,而是通过Collection接口使用它们。

随着时间的推移,我确实发现当我需要一个泛型集合时,或多或少地放入一些东西,然后迭代它。如果我需要更多的进化行为(比如随机访问,排序或单一性检查),那么我可能会更改已使用的实现,但在此之前我会将使用过的接口更改为最合适的。通过这种方式,我可以确保在提供功能之前专注于优化和实施。

答案 2 :(得分:1)

ArrayList基本上包含一个数组(这就是它被称为ArrayList的原因)。在任意位置添加/删除等操作都是以直接的方式完成的,所以如果你不使用它们 - 对性能没有任何影响。

答案 3 :(得分:0)

如果订购和重复不是问题,而且仅用于存储,

我使用ArrayList,因为它实现了所有列表操作。从未感觉到这些操作存在任何性能问题(从未影响我的项目)。实际上使用这些操作具有简单的用途和优点。我不需要关心其内部管理方式。

只有当多个线程访问此列表时,我才使用Vector,因为它的方法是同步的。

ArrayList和Vector也是您首先学习的集合:)。

答案 4 :(得分:0)

这取决于你对它的了解。

如果我不知道,我倾向于寻找一个链表,因为最后添加/删除的惩罚是不变的。如果我对它的最大大小有一个粗略的想法,我会选择具有指定容量的arraylist,因为如果估计好,它会更快。如果我真的知道我倾向于使用正常数组的确切大小;虽然那不是真正的集合类型。

答案 5 :(得分:0)

  

我意识到所有关于性能的讨论都毫无意义,唯一真正重要的是测量。

这不一定是真的。

如果您了解应用程序的工作原理告诉您某些集合将会非常大,那么选择正确的集合类型是个好主意。但正确的集合类型依赖关键如何使用集合;即在算法上。

例如,如果您的应用程序很可能通过测试集合是否包含给定对象,那么Collection.contains(Object) O(N) LinkedList<T> ArrayList<T> HashMap<T, Integer> } 可能意味着它们都不是合适的集合类型。相反,也许您应该将集合表示为Integer,其中T表示“集合”中O(1)的出现次数。这将为您提供O(1)测试和删除,代价是更多的空间开销和更慢(尽管仍然{{1}})插入。

但要强调的是,如果您可能正在处理非常大的集合,那么就不应该存在“默认”集合类型。您需要在算法的上下文中考虑集合。 (另一方面,如果集合总是很小,那么你选择的集合类型可能差别不大。)