我应该使用哪个 Java 集合?

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

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

有哪些资源和“备忘单”可以帮助人们在 Java 编程时选择正确的 Collection 来使用?人们如何知道应该使用哪些 List、 Set 和 Map 实现?

61685 次浏览

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

这个流程图并不试图涵盖同步访问、线程安全等内容或遗留集合,但它确实涵盖了3个标准 预备、3个标准 地图和2个标准 名单

enter image description here

这个图像是为这个问题的答案创建的,并且使用 知识共享署名4.0国际许可证。授权。最简单的属性是通过链接到这个问题或这个答案。

其他资源

可能最有用的其他参考资料是 Oracle 文档中描述每个 收集的下面一页。

HashSet vs TreeSet

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

数组列表与 LinkedList

详细讨论: 何时在数组列表上使用 LinkedList?

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

  1. Collection 是包含称为“ element”(同一类型)的数据的任何内容。

  2. List 是一个 索引数据集合,其中每个元素都有一个索引。

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

    典型操作: 得到 n 个元素。

  3. Set 是一个 一袋元素,每个元素只有一次(使用它们的 equals()方法区分元素)。

    集合中的数据主要是为了知道 什么数据的存在而存储的。

    典型操作: 告诉列表中是否存在元素。

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

    地图中的数据可以通过它们的键进行搜索。

    典型操作: 根据 ID 获取元素(其中 ID 为任何类型,而不仅仅是 List 中的 int)。

不同之处

  • Set vs. Map: 在 Set you 搜索 data 他们自己中,而在 Map 用他们的钥匙中。

    注意。标准库集的实现方式确实如下: 一个映射,其中键是 Set 元素本身,并带有一个虚拟值。

  • List 与 Map: 在 List 中,您通过元素的 int索引(在 List 中的位置)访问元素,而在 Map 中通过它们的键访问任何类型的 os (通常为 ID)

  • List vs Set: 在 List 中,元素被它们的位置绑定并且可以被复制,而在 Set 中,元素只是“存在”(或者不存在)并且是唯一的(在 equals()或者 compareTo()中是 SortedSet的意思)

这很简单: 如果需要存储映射到键的值,可以使用 Map 接口,否则对可能重复的值使用 List,如果不希望集合中出现重复的值,则最后使用 Set 接口。

这里是完整的解释 http://javatutorial.net/choose-the-right-java-collection,包括流程图等

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

Collection : 表示一个无序的“包”的接口,称为“元素”。“下一个”元素是未定义的(随机的)。

  • Set : 表示没有重复的 Collection的接口。
    • HashSet : 由 Hashtable支持的 Set。当排序不重要时,最快和最小的内存使用。
    • LinkedHashSet : 在 插入顺序中添加链表以关联元素的 HashSet。“ next”元素是最近插入的下一个元素。
    • TreeSet : 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)来找到它的位置。在大多数情况下ArrayListLinkedList更受欢迎。
    • LinkedList : 由一组对象支持的 List,每个对象与它的“前一个”和“下一个”邻居相连。LinkedList也是 QueueDeque。从第一个或最后一个元素开始访问元素,然后遍历,直到达到所需的索引。插入和删除,一旦通过遍历达到所需的索引只是重新映射直接邻居链接,以指向新元素或绕过现已删除的元素。
  • Map : 表示 Collection的接口,其中每个元素都有一个可识别的“键”——每个元素是一个键-值对。
    • HashMap : 一个 Map,其中键是无序的,由一个 Hashtable支持。
    • LinkedhashMap : 钥匙由 插入顺序订购。
    • TreeMap : Map,键由 Comparator排序(通常是自然排序)。
  • Queue : 表示 Collection的接口,其中元素通常被添加到一端,并从另一端移除(FIFO: first-in,first-out)。
  • Stack : 表示 Collection的接口,其中元素通常从同一端添加(推送)和删除(弹出)(LIFO: last-in,first-out)。
  • Deque : “双尾队列”的简称,通常发音为“甲板”。一个链表,通常只添加到两端(而不是中间)并从两端读取。

基本收集图表:

diagram

将插入元素与 ArrayListLinkedList进行比较:

diagram

公共收藏,公共收藏 enter image description here

地图

如果选择一个 Map,那么我制作了这个表格来总结与 Java11绑定的十个实现中的每一个的特性。

Table of map implementations in Java 11, comparing their features