关于算法:我应该使用哪个Java Collection?

Which Java Collection should I use?

在这个问题中如何在C ++ 11中有效地选择标准库容器? 是一个在选择C ++集合时使用的方便流程图。

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

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


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

此流程图不会尝试涵盖同步访问,线程安全等内容或旧版集合,但它涵盖了3个标准集,3个标准映射和2个标准列表。

enter image description here

此图片是为此答案而创建的,并根据知识共享署名4.0国际许可协议授权。最简单的归因是链接到这个问题或这个答案。

其他资源

可能最有用的其他参考是oracle文档中的以下页面,其中描述了每个Collection。

HashSet与TreeSet

这里有一个关于何时使用HashSetTreeSet的详细讨论:
Hashset与Treeset

ArrayList与LinkedList

详细讨论:何时使用LinkedList而不是ArrayList?


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

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

  • Set:表示Collection且没有重复的接口。

    • HashSet:由Hashtable支持的Set。订购时最快和最小的内存使用量并不重要。
    • LinkedHashSet:A HashSet,添加了一个链接列表,用于按插入顺序关联元素。"next"元素是最近插入的元素。
    • TreeSet:A Set,其中元素按Comparator排序(通常是自然排序)。最慢和最大的内存使用,但基于比较器的排序是必需的。
    • EnumSet:针对单个枚举类型定制的极其快速且高效的Set
  • List:表示Collection的接口,其元素按顺序排列,每个元素都有一个表示其位置的数字索引,其中0是第一个元素,(length - 1)是最后一个元素。

    • ArrayList:由数组支持的List,其中数组的长度(称为"容量")至少与元素数量(列表的"大小")一样大。当大小超过容量时(添加(capacity + 1)-th元素时),将使用(new length * 1.5)的新容量重新创建阵列 - 这种重新创建很快,因为它使用System.arrayCopy()。删除和插入/添加元素需要将所有相邻元素(右侧)移入或移出该空间。访问任何元素都很快,因为它只需要计算(element-zero-address + desired-index * element-size)来找到它的位置。在大多数情况下,ArrayList优于LinkedList
    • LinkedList:由一组对象支持的List,每个对象链接到其"前一个"和"下一个"邻居。 A LinkedList也是QueueDeque。从第一个或最后一个元素开始访问元素,并遍历直到达到所需的索引。一旦通过遍历到达所需索引,插入和删除是一个简单的问题,即只重新映射直接邻居链接以指向新元素或绕过现在删除的元素。
  • Map:表示Collection的接口,其中每个元素具有标识"密钥" - 每个元素是键值对。

    • HashMapMap,其中键是无序的,并由Hashtable支持。
    • LinkedhashMap:键按插入顺序排序。
    • TreeMap:A Map其中键按Comparator排序(通常是自然排序)。
  • Queue:表示Collection的接口,其中元素通常添加到一端,并从另一端移除(FIFO:先进先出)。
  • Stack:表示Collection的接口,其中元素通常从同一端添加(推送)和删除(弹出)(LIFO:last-in,first-out)。
  • Deque:"双端队列"的缩写,通常发音为"deck"。通常仅添加到任一端(而不是中间)的链接列表。

基本集合图:

diagram

比较元素与ArrayListLinkedList的插入:

diagram


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

  • 集合是包含称为"元素"(相同类型)的数据的任何东西。没有更具体的假设。

  • List是一个索引的数据集合,其中每个元素都有一个索引。像数组一样,但更灵活。

    列表中的数据保持插入顺序。

    典型操作:获取第n个元素。

  • Set是一包元素,每个元素只有一次(元素使用equals()方法区分。

    存储集中的数据主要是为了知道那里有什么数据。

    典型操作:判断列表中是否存在元素。

  • Map类似于List,但不是通过整数索引访问元素,而是通过其键(任何对象)访问它们。像PHP中的数组:)

    地图中的数据可通过其密钥进行搜索。

    典型的操作:通过其ID获取元素(其中ID是任何类型,不仅是int,如List的情况)。

  • 差异

    • 设置和映射:在设置中,您可以自己搜索数据,而在地图中按键。

    • 列表和映射:在列表中,您可以通过int索引(列表中的位置)访问元素,而在Map中按键访问任何类型的操作符(通常为:ID)

    • List和Set:在List中元素由它们的位置绑定并且可以是重复的,而在Set中元素只是"存在"(pr不存在)并且是唯一的(在equals()compareTo()的含义中SortedSet)


    这很简单:如果您需要存储映射到它们的键的值,请转到Map接口,否则使用List作为可能重复的值,如果您不想在集合中使用重复值,最后使用Set接口。

    以下是http://javatutorial.net/choose-the-right-java-collection的完整说明,包括流程图等


    我应该使用哪个Java Collection?

    这取决于您要解决的问题或您有哪些要求。

    例子 :

  • 您希望在存储元素时对元素进行排序吗? HashSet的
  • 你想要(Key,Value)对存储吗? HashMap中
  • 您是否希望保留插入时元素的顺序? ArrayList,LinkedList
  • 您想要对(键,值)对中的键进行排序吗? - 强文
  • 你想实现一个堆栈来解决你的问题吗? - 堆叠
  • 您想要FIFO(先进先出)访问吗? - 队列
  • 您是否只想存储UNIQUE元素? - 哈希集
  • 你想在存储(Key,Value)时允许密钥为"Null"吗? - HashMap
  • 你想要(Key,Value)对没有NULL值吗?哈希表