Rule of thumb for choosing an implementation of a Java Collection?任何人都有很好的经验法则可以在Java Collection接口的不同实现(例如List,Map或Set)之间进行选择? 例如,通常,为什么或在什么情况下,我更喜欢使用Vector或ArrayList,Hashtable或HashMap? 我真的很喜欢Sergiy Kovalchuk博客文章中的备忘单:
Alexander Zagniotov的流程图更为详细,但不幸的是它是离线的。但是,Wayback Machine有一个博客副本:
我假设您从上述答案中知道List,Set和Map之间的区别。为什么要在他们的实现类之间进行选择是另一回事。例如: 列表: 组: 映射:HashMap和TreeMap的性能和行为与Set实现平行。 不应该使用Vector和Hashtable。它们是新的Collection层次结构发布之前的同步实现,因此速度很慢。如果需要同步,请使用Collections.synchronizedCollection()。 我总是根据用例逐案做出决定,例如:
然后,我简要介绍了我的第5版Java,比较了大约20种左右的选项。第五章中有一些漂亮的表格,可以帮助您找出合适的表格。 好吧,也许如果我袖手旁观,简单的ArrayList或HashSet可以解决问题,我将不会全看。 ;),但是如果我的预期用途有任何复杂之处,那么您肯定我在书中。顺便说一句,尽管我认为Vector应该是"旧帽子"-我已经好几年没有使用过了。 从理论上讲,存在一些有用的Big-Oh折衷方案,但实际上,这些折衷方案几乎没有关系。
在实际的基准测试中,即使使用大型列表和诸如"在前面有很多插入"之类的操作, 我的规则是: 关于第一个问题... 列表,地图和集合具有不同的用途。我建议在http://java.sun.com/docs/books/tutorial/collections/interfaces/index.html上阅读有关Java Collections Framework的内容。 更具体一点:
关于第二个问题... Vector和ArrayList之间的主要区别是前者是同步的,后者是不同步的。您可以在实践中阅读有关Java并发性的更多信息。 Hashtable(注意T不是大写字母)和HashMap之间的区别是相似的,前者是同步的,后者是不同步的。 我想说,偏爱一个或另一个实现并没有经验法则,这实际上取决于您的需求。 对于未排序的最佳选择,十分之九以上是:ArrayList,HashMap,HashSet。 Vector和Hashtable是同步的,因此可能会慢一些。很少有人想要同步的实现,而且当您执行同步操作时,它们的接口还不够丰富,因此无法使用同步。对于Map,ConcurrentMap添加了额外的操作以使该接口有用。 ConcurrentHashMap是ConcurrentMap的良好实现。 LinkedList几乎从来不是一个好主意。即使您进行了大量插入和删除操作,但是如果您使用索引来指示位置,那么也需要遍历列表以找到正确的节点。 ArrayList几乎总是更快。 对于"地图"和"集合",哈希变体的速度将比树/排序的速度快。哈希算法倾向于具有O(1)性能,而树将是O(log n)。 正如其他答案中所建议的那样,根据用例,有不同的方案可以使用正确的收集。我列出几点 数组列表:
链表:
HashSet的:
HashMap的:
Vector和Hashtable已同步,因此速度较慢;如果需要同步,请使用Collections.synchronizedCollection()。 列表允许重复项,而集合仅允许一个实例。 每当需要执行查找时,我都会使用Map。 对于特定的实现,"地图"和"集合"有保留顺序的变体,但很大程度上取决于速度。我倾向于将ArrayList用于较小的列表,将HashSet用于较小的集合,但是有许多实现(包括您自己编写的任何实现)。 HashMap在地图中非常常见。除了"合理地小"以外,您还必须开始担心内存,以便在算法上更加具体。 如果您对硬数字感兴趣,则此页面上有许多动画图像以及用于测试LinkedList与ArrayList的示例代码。 编辑:我希望以下链接能够演示这些东西实际上只是工具箱中的项目,您只需要考虑一下您的需求是什么:请参阅Maps,List和Set的Commons-Collections版本。 好吧,这取决于您的需求。 一般准则是: List是一个集合,其中数据按插入顺序保留,并且每个元素都获得索引。 Set是一袋没有重复的元素(如果重新插入相同的元素,则不会添加)。 数据没有顺序的概念。 映射您可以通过键访问和写入数据元素,这些键可以是任何可能的对象。
有关Java集合的更多信息,请查看本文。 我发现Bruce Eckel的《 Java思维》非常有用。他很好地比较了不同的收藏。我曾经保存过一张他发表的图表,该图表显示了我的立方体墙上的继承继承作为快速参考。我建议您做的一件事是记住线程安全性。性能通常意味着线程不安全。 |