繁体   English   中英

我应该使用哪个 Java 集合?

[英]Which Java Collection should I use?

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

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

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

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

此流程图并未尝试涵盖诸如同步访问、线程安全等或遗留集合之类的内容,但它确实涵盖了 3 个标准Set 、3 个标准Map和 2 个标准List

在此处输入图片说明

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

其他资源

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

HashSet 与 TreeSet

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

ArrayList 与 LinkedList

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

主要非并发、非同步集合的总结

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

  • Set :表示没有重复的Collection的接口。
    • HashSet :由Hashtable支持的Set 当排序不重要时,最快和最小的内存使用量。
    • LinkedHashSet :一个HashSet ,添加了一个链接列表以按插入顺序关联元素。 “下一个”元素是下一个最近插入的元素。
    • 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)即可找到它的位置。 在大多数情况下ArrayList优于LinkedList
    • LinkedList :由一组对象支持的List ,每个对象都链接到其“上一个”和“下一个”邻居。 LinkedList也是QueueDeque 访问元素从第一个或最后一个元素开始,并遍历直到达到所需的索引。 插入和删除,一旦通过遍历达到所需的索引,只需重新映射直接相邻链接以指向新元素或绕过现在删除的元素即可。
  • Map :表示Collection的接口,其中每个元素都有一个标识“键”——每个元素都是一个键值对。
    • HashMap :键是无序的Map ,并由Hashtable支持。
    • LinkedhashMap :键按插入顺序排列
    • TreeMap :一个Map ,其中键由Comparator排序(通常是自然排序)。
  • Queue :表示Collection的接口,其中元素通常添加到一端,然后从另一端删除(FIFO:先进先出)。
  • Stack :表示Collection的接口,其中元素通常从同一端添加(推送)和删除(弹出)(LIFO:后进先出)。
  • Deque :“双端队列”的Deque ,通常发音为“deck”。 一个通常只添加到两端(而不是中间)和从中读取的链表。

基本集合图:

图表

将元素插入与ArrayListLinkedList

图表

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

  1. 集合是任何保存称为“元素”(相同类型)的数据的东西。 没有更具体的假设。

  2. 列表是数据的索引集合,其中每个元素都有一个索引。 类似于数组的东西,但更灵活。

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

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

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

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

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

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

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

    典型操作:通过其 ID 获取元素(其中 ID 是任何类型,而不仅仅是像 List 那样的int )。

差异

  • Set vs. Map:在 Set 中你可以自己搜索数据,而在 Map 中则是通过他们的 key

    NB 标准库 Sets 确实是这样实现的:一个映射,其中键是 Set 元素本身,并带有一个虚拟值。

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

  • List vs. Set:在 List 中,元素受它们的位置约束并且可以重复,而在 Set 中元素只是“存在”(或不存在)并且是唯一的(在equals()compareTo()的意义上compareTo()对于SortedSet )

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

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

地图

如果选择Map ,我制作了这个表格,总结了与 Java 11 捆绑在一起的十个实现中每一个的特性。

Java 11 中的地图实现表,比较它们的特性

公共集合, 公共集合在此处输入图片说明

我应该使用哪个Java Collection?

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

例子 :

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM