我应该使用什么Java Collection?

问题

在这个问题中,How can I efficiently select a Standard Library container in C++11?是一个在选择C集合时使用的方便流程图。

我认为这对于那些不确定他们应该使用哪个集合的人来说是一个有用的资源,所以我试图为Java找到类似的流程图而无法这样做。

什么资源和"备忘单"可以帮助人们选择在Java编程时使用的正确的集合?人们如何知道应该使用哪些List,Set和Map实现?


#1 热门回答(218 赞)

由于我找不到类似的流程图,我决定自己制作一个。

此流程图不会尝试覆盖诸如同步访问,线程安全等或旧版集合之类的内容,但它确实涵盖3标准Sets,3 standardMaps和2 standardLists。

enter image description here
这张图片是为这个答案而创建,并根据aCreative Commons Attribution 4.0 International License.许可。最简单的归属是链接到这个问题或这个答案.其他资源
可能最有用的其他参考是oracle文档中的以下页面,其中描述了每个Collection
HashSet vs TreeSet
有详细讨论何时使用HashSetTreeSetHashset vs Treeset
ArrayList vs LinkedList
详细讨论:When to use LinkedList over ArrayList?


#2 热门回答(46 赞)

#主要非并发,非同步集合的摘要

Collection:表示项目的无序"包"的接口,称为"元素"。 "next"元素未定义(随机)。

  • Set:表示Collection没有重复的接口。 HashSet:由Hashtable支持的Set。订购时最快和最小的内存使用量并不重要。 LinkedHashSet:一个HashSet,添加了一个链接列表,用于按插入顺序关联元素。 "next"元素是最近插入的元素。 TreeSet:一个集合,其中元素由比较器排序(通常是自然排序)。最慢和最大的内存使用量,但基于比较器的排序是必需的。 EnumSet:为单个枚举类型定制的极其快速且高效的Set。
  • List:表示Collection的接口,其元素是有序的,每个元素都有一个表示其位置的数字索引,其中zero是第一个元素,(length - 1)是最后一个元素。 ArrayList:由数组支持的List,其中数组的长度(称为"capacity")至少与元素数量(列表的"size")一样大。当大小超过容量时(添加(容量1)元素时),使用新容量(新长度* 1.5)重新创建数组 - 这种重新创建很快,因为它使用System.arrayCopy()。删除和插入/添加元素需要将所有相邻元素(向右)移入或移出该空间。访问任何元素都很快,因为它只需要计算(element-zero-address desired-index * element-size)来查找它的位置。在大多数情况下,ArrayList比LinkedList更受欢迎。 LinkedList:由一组对象支持的List,每个对象链接到其"previous"和"next"邻居。 LinkedList也是Queue和Deque。从第一个或最后一个元素开始访问元素,并遍历直到达到所需的索引。一旦通过遍历达到所需索引,插入和删除是一个小问题,即只重新映射直接邻居链接以指向新元素或绕过现在删除的元素。
  • Map:表示Collection的接口,其中每个元素都有一个标识"key" - 每个元素都是一个键值对。 HashMap:一个映射,其中键是无序的,并由Hashtable支持。 LinkedhashMap:键按插入顺序排序。 TreeMap:一个 Map ,其中键由比较器排序(通常是自然排序)。
  • 队列:表示集合的接口,其中元素通常添加到一端,并从另一端移除(FIFO:先进先出)。
  • Stack:表示Collection的接口,其中元素通常从同一端添加(推送)和删除(弹出)(LIFO:last-in,first-out)。
  • Deque:"双端队列"的缩写,通常发音为"deck"。通常仅添加到任一端(而不是中间)的链接列表。

基本集合图:

diagram

比较元素与ArrayListLinkedList的插入:

diagram


#3 热门回答(9 赞)

更简单的图片就在这里。故意简化!

  • 集合是任何包含称为"元素"(相同类型)的数据的东西。没有更具体的假设。
  • List是一个索引的数据集合,其中每个元素都有一个索引。像阵列一样,但更灵活。列表中的数据保持插入顺序。
  • Set是一个元素包,每个元素只有一次(使用equals()方法区分元素。集合中的数据主要是为了知道那里有什么数据。
  • Map类似于List,但不是通过整数索引访问元素,而是通过其键(任何对象)访问它们。就像PHP中的数组一样:) Map 中的数据可以通过其密钥进行搜索。 Set和Map之间的主要区别在于Set中你自己搜索数据,而在 Map 中按键。