在这个问题中How can I efficiently select a Standard Library container in C++11?是一个方便的流程图,用于选择C++集合。我应该使用什么Java集合?
我认为这是一个有用的资源,不知道他们应该使用哪个集合,因此我试图找到类似的Java流程图,但无法这样做。
什么资源和“备忘单”可用于帮助人们在Java编程时选择正确的集合?人们如何知道他们应该使用什么List,Set和Map实现?
在这个问题中How can I efficiently select a Standard Library container in C++11?是一个方便的流程图,用于选择C++集合。我应该使用什么Java集合?
我认为这是一个有用的资源,不知道他们应该使用哪个集合,因此我试图找到类似的Java流程图,但无法这样做。
什么资源和“备忘单”可用于帮助人们在Java编程时选择正确的集合?人们如何知道他们应该使用什么List,Set和Map实现?
由于找不到类似的流程图,我决定自己做一个。
该流程图并不试图掩盖的东西一样同步访问,线程安全等或传统的集合,但它确实涵盖3个标准设置 S,3个标准地图 s和标准名单小号。
这个影像对于这个答案创建并下Creative Commons Attribution 4.0 International License.最简单的归属许可是通过链接要么这个问题或这个答案。
其他资源
可能是最有用的其它参考是从描述每个Collection Oracle文档以下页面。
HashSet的VS TreeSet的
有何时使用HashSet
或TreeSet
这里详细讨论: Hashset vs Treeset
的ArrayList VS LinkedList的
甚至s执行图片在这里。故意简化!
收集是任何保持数据称为 “元素”(同一类型的)。没有更具体的假设。
列表是索引集合,其中每个元素有一个索引数据。像数组一样,但更灵活。
列表中的数据保持插入顺序。
集是袋元件,每个元素仅仅一次(其中的元件使用他们equals()
方法有区别的。
设置中的数据主要存储只是为了知道什么数据在那里。
地图是类似的名单,但不是由他们的整数索引访问元素,您可以通过他们的关键访问它们,这是任何对象。就像PHP中的数组:)
地图中的数据可以通过其密钥进行搜索。
设置和地图之间的主要不同的是,在设置你搜索数据自己,而在地图通过他们的关键。
这很简单:如果你需要存储值映射到它们的密钥去Map接口,否则使用清单可以重复值和最终使用Set接口,如果你不想重复值在您的收藏。
下面是完整解释,包括流程图等
Collection
:表示项目的无序“袋”的接口,被称为“元件”。 “下一个”元素是未定义的(随机)。
Set
:代表Collection
没有重复的接口。
HashSet
:A Set
支持Hashtable
。订购时最快和最小的内存使用量并不重要。LinkedHashSet
:A HashSet
增加了一个链接列表来关联中的元素插入顺序。 “下一个”元素是下一个最近插入的元素。TreeSet
:A Set
其中元件按Comparator
(通常为natural ordering)排序。最慢和最大的内存使用情况,但对于基于比较器的排序而言是必需的EnumSet
:为单枚枚举类型定制的极其快速高效的Set
。List
:表示的接口的Collection
其元素是有序的,并且每个具有表示其位置,其中零是第一要素,和(length - 1)
是最后一个数字索引。
ArrayList
:甲List
由阵列,其中所述阵列具有的长度(所谓的“容量”),其是至少为(列表的“尺寸”)元件的数量一样大的支持。当尺寸超过容量时(添加(capacity + 1)-th
元素时),将以新容量(new length * 1.5)
重新创建阵列 - 由于使用System.arrayCopy()
,因此重新创建速度很快。删除和插入/添加元素需要将所有相邻元素(右侧)移入或移出该空间。访问任何元素都很快,因为它只需要计算(element-zero-address + desired-index * element-size)
就可以找到它的位置。 In most situations,ArrayList
优于LinkedList
。LinkedList
:A List
由一组对象支持,每个对象链接到它的“上一个”和“下一个”邻居。 A LinkedList
也是Queue
和Deque
。访问元素从第一个或最后一个元素开始,遍历直到达到所需的索引。插入和删除,一旦通过遍历达到所需的索引,则只需将直接相邻链接重新映射为指向新元素或绕过现在删除的元素,这是一件微不足道的事情。Map
:代表Collection
的界面,其中每个元素都有一个标识“键” - 每个元素都是一个键值对。
HashMap
:A Map
其中密钥是无序的,并且由Hashtable
支持。LinkedhashMap
:钥匙按订购。TreeMap
:A Map
其中密钥按Comparator
(通常为自然顺序)排序。Queue
:一个表示Collection
其中元素,典型地,加入到一个端部,并从另一个(:先入先出FIFO)去除的接口。Stack
:代表Collection
的接口,其中通常从相同的末端(LIFO:后进先出)添加(推送)和移除(弹出)元素。Deque
:“双排队列”的缩写,通常发音为“甲板”。通常只添加到任一端(并非中间)并从中读取的链接列表。基本集合图:
元素的插入与ArrayList
和LinkedList
比较:
最好总结一下,你可以在任何地方:) – roottraveller
你应该添加'Vector','HashTable'和'PriorityQueue' ... – roottraveller
不错!但我不同意你的'LinkedList'与'ArrayList'的决定。首先,如果列表的大小很大,那么最好使用LinkedList。 'LinkedList'具有每个元素的开销,所以它在内存消耗方面比'ArrayList'渐近。另外,如果大部分访问都在列表的末尾,那么'ArrayList'是最好的,因为它提供了恒定时间的随机元素访问。访问“LinkedList”的第n个元素是一个“O(n)”操作。 ...实际上,使用链表的决定应该几乎是“不”。 –
@MattBall我很同意你的看法。然而Java'LinkedList'是一个双链表,所以在开始和结束时访问都很快。你会注意到,在推荐使用'LinkedList'之前,所有三个问题都必须回答yes,所以换句话说,我同意你的观点,在大多数情况下,答案是否定的。诸如队列和出队之类的事情,你不断地在列表的末尾添加和删除东西,这些都是对LinkedList很好的用例。 –
@MattBall内存使用情况是一个更棘手的情况,因为当一个LinkedList对每个元素使用更多内存时...... ArrayList从不释放内存。这意味着如果你有一个列表有时会增长到一个很大的大小,但通常很小,那么'ArrayList'会给内存带来更糟的性能。与其包含的元素相比,“List”本身的内存开销通常(虽然不总是)很小。 –