简体   繁体   English

我应该使用哪个 Java 集合?

[英]Which Java Collection should I use?

In this question How can I efficiently select a Standard Library container in C++11?在这个问题中, 如何在 C++11 中有效地选择标准库容器? is a handy flow chart to use when choosing C++ collections.是选择 C++ 集合时使用的方便流程图。

I thought that this was a useful resource for people who are not sure which collection they should be using so I tried to find a similar flow chart for Java and was not able to do so.我认为对于不确定应该使用哪个集合的人来说,这是一个有用的资源,所以我试图为 Java 找到一个类似的流程图,但没有找到。

What resources and "cheat sheets" are available to help people choose the right Collection to use when programming in Java?有哪些资源和“备忘单”可以帮助人们在 Java 编程时选择正确的 Collection? How do people know what List, Set and Map implementations they should use?人们如何知道他们应该使用哪些 List、Set 和 Map 实现?

Since I couldn't find a similar flowchart I decided to make one myself.由于找不到类似的流程图,我决定自己制作一个。

This flow chart does not try and cover things like synchronized access, thread safety etc or the legacy collections, but it does cover the 3 standard Set s, 3 standard Map s and 2 standard List s.此流程图并未尝试涵盖诸如同步访问、线程安全等或遗留集合之类的内容,但它确实涵盖了 3 个标准Set 、3 个标准Map和 2 个标准List

在此处输入图片说明

This image was created for this answer and is licensed under a Creative Commons Attribution 4.0 International License.此图像是为此答案创建的,并根据知识共享署名 4.0 国际许可协议获得许可。 The simplest attribution is by linking to either this question or this answer.最简单的归因是链接到这个问题或这个答案。

Other resources其他资源

Probably the most useful other reference is the following page from the oracle documentation which describes each Collection .可能最有用的其他参考资料是 oracle 文档中描述每个Collection的以下页面。

HashSet vs TreeSet HashSet 与 TreeSet

There is a detailed discussion of when to use HashSet or TreeSet here: Hashset vs Treeset这里有关于何时使用HashSetTreeSet的详细讨论: Hashset vs Treeset

ArrayList vs LinkedList ArrayList 与 LinkedList

Detailed discussion: When to use LinkedList over ArrayList?详细讨论: 何时使用 LinkedList 而不是 ArrayList?

Summary of the major non-concurrent, non-synchronized collections主要非并发、非同步集合的总结

Collection : An interface representing an unordered "bag" of items, called "elements". Collection :一个接口,表示一个无序的“袋子”项目,称为“元素”。 The "next" element is undefined (random). “下一个”元素未定义(随机)。

  • Set : An interface representing a Collection with no duplicates. Set :表示没有重复的Collection的接口。
    • HashSet : A Set backed by a Hashtable . HashSet :由Hashtable支持的Set Fastest and smallest memory usage, when ordering is unimportant.当排序不重要时,最快和最小的内存使用量。
    • LinkedHashSet : A HashSet with the addition of a linked list to associate elements in insertion order . LinkedHashSet :一个HashSet ,添加了一个链接列表以按插入顺序关联元素。 The "next" element is the next-most-recently inserted element. “下一个”元素是下一个最近插入的元素。
    • TreeSet : A Set where elements are ordered by a Comparator (typically natural ordering ). TreeSet :一个Set ,其中元素由Comparator 排序(通常是自然排序)。 Slowest and largest memory usage, but necessary for comparator-based ordering.最慢和最大的内存使用量,但对于基于比较器的排序是必需的。
    • EnumSet : An extremely fast and efficient Set customized for a single enum type. EnumSet :为单个枚举类型定制的极其快速和高效的Set
  • List : An interface representing a Collection whose elements are ordered and each have a numeric index representing its position, where zero is the first element, and (length - 1) is the last.List :表示一个Collection的接口,它的元素是有序的,每个元素都有一个数字索引来表示它的位置,其中 0 是第一个元素, (length - 1)是最后一个元素。
    • ArrayList : A List backed by an array, where the array has a length (called "capacity") that is at least as large as the number of elements (the list's "size"). ArrayList :由数组支持的List ,其中数组的长度(称为“容量”)至少与元素数量(列表的“大小”)一样大。 When size exceeds capacity (when the (capacity + 1)-th element is added), the array is recreated with a new capacity of (new length * 1.5) --this recreation is fast, since it uses System.arrayCopy() .当大小超过容量时(当添加第(capacity + 1)-th元素时),将使用(new length * 1.5)的新容量重新创建数组——这种重新创建速度很快,因为它使用System.arrayCopy() Deleting and inserting/adding elements requires all neighboring elements (to the right) be shifted into or out of that space.删除和插入/添加元素需要将所有相邻元素(向右)移入或移出该空间。 Accessing any element is fast, as it only requires the calculation (element-zero-address + desired-index * element-size) to find it's location.访问任何元素都很快,因为它只需要计算(element-zero-address + desired-index * element-size)即可找到它的位置。 In most situations , an ArrayList is preferred over a LinkedList . 在大多数情况下ArrayList优于LinkedList
    • LinkedList : A List backed by a set of objects, each linked to its "previous" and "next" neighbors. LinkedList :由一组对象支持的List ,每个对象都链接到其“上一个”和“下一个”邻居。 A LinkedList is also a Queue and Deque . LinkedList也是QueueDeque Accessing elements is done starting at the first or last element, and traversing until the desired index is reached.访问元素从第一个或最后一个元素开始,并遍历直到达到所需的索引。 Insertion and deletion, once the desired index is reached via traversal is a trivial matter of re-mapping only the immediate-neighbor links to point to the new element or bypass the now-deleted element.插入和删除,一旦通过遍历达到所需的索引,只需重新映射直接相邻链接以指向新元素或绕过现在删除的元素即可。
  • Map : An interface representing an Collection where each element has an identifying "key"--each element is a key-value pair. Map :表示Collection的接口,其中每个元素都有一个标识“键”——每个元素都是一个键值对。
    • HashMap : A Map where keys are unordered, and backed by a Hashtable . HashMap :键是无序的Map ,并由Hashtable支持。
    • LinkedhashMap : Keys are ordered by insertion order . LinkedhashMap :键按插入顺序排列
    • TreeMap : A Map where keys are ordered by a Comparator (typically natural ordering). TreeMap :一个Map ,其中键由Comparator排序(通常是自然排序)。
  • Queue : An interface that represents a Collection where elements are, typically, added to one end, and removed from the other (FIFO: first-in, first-out). Queue :表示Collection的接口,其中元素通常添加到一端,然后从另一端删除(FIFO:先进先出)。
  • Stack : An interface that represents a Collection where elements are, typically, both added (pushed) and removed (popped) from the same end (LIFO: last-in, first-out). Stack :表示Collection的接口,其中元素通常从同一端添加(推送)和删除(弹出)(LIFO:后进先出)。
  • Deque : Short for "double ended queue", usually pronounced "deck". Deque :“双端队列”的Deque ,通常发音为“deck”。 A linked list that is typically only added to and read from either end (not the middle).一个通常只添加到两端(而不是中间)和从中读取的链表。

Basic collection diagrams:基本集合图:

图表

Comparing the insertion of an element with an ArrayList and LinkedList :将元素插入与ArrayListLinkedList

图表

Even simpler picture is here.更简单的图片在这里。 Intentionally simplified!有意简化!

  1. Collection is anything holding data called "elements" (of the same type). 集合是任何保存称为“元素”(相同类型)的数据的东西。 Nothing more specific is assumed.没有更具体的假设。

  2. List is an indexed collection of data where each element has an index. 列表是数据的索引集合,其中每个元素都有一个索引。 Something like the array, but more flexible.类似于数组的东西,但更灵活。

    Data in the list keep the order of insertion.列表中的数据保持插入顺序。

    Typical operation: get the n-th element.典型操作:获取第 n 个元素。

  3. Set is a bag of elements , each elements just once (the elements are distinguished using their equals() method. Set是一个元素包,每个元素只有一次(使用它们的equals()方法区分元素。

    Data in the set are stored mostly just to know what data are there.存储集中的数据主要是为了知道那里有什么数据。

    Typical operation: tell if an element is present in the list.典型操作:判断一个元素是否存在于列表中。

  4. Map is something like the List, but instead of accessing the elements by their integer index, you access them by their key , which is any object. Map类似于 List,但不是通过整数索引访问元素,而是通过它们的key访问它们,它是任何对象。 Like the array in PHP :)就像 PHP 中的数组 :)

    Data in Map are searchable by their key. Map 中的数据可以通过它们的键进行搜索。

    Typical operation: get an element by its ID (where ID is of any type, not only int as in case of List).典型操作:通过其 ID 获取元素(其中 ID 是任何类型,而不仅仅是像 List 那样的int )。

The differences差异

  • Set vs. Map: in Set you search data by themselves , whilst in Map by their key . Set vs. Map:在 Set 中你可以自己搜索数据,而在 Map 中则是通过他们的 key

    NB The standard library Sets are indeed implemented exactly like this: a map where the keys are the Set elements themselves, and with a dummy value. NB 标准库 Sets 确实是这样实现的:一个映射,其中键是 Set 元素本身,并带有一个虚拟值。

  • List vs. Map: in List you access elements by their int index (position in List), whilst in Map by their key which os of any type (typically: ID) List vs. Map:在 List 中,您可以通过它们的int索引(在 List 中的位置)访问元素,而在 Map 中通过它们的键访问任何类型的 os(通常:ID)

  • List vs. Set: in List the elements are bound by their position and can be duplicate, whilst in Set the elements are just "present" (or not present) and are unique (in the meaning of equals() , or compareTo() for SortedSet ) List vs. Set:在 List 中,元素受它们的位置约束并且可以重复,而在 Set 中元素只是“存在”(或不存在)并且是唯一的(在equals()compareTo()的意义上compareTo()对于SortedSet )

It is simple: if you need to store values with keys mapped to them go for the Map interface, otherwise use List for values which may be duplicated and finally use the Set interface if you don't want duplicated values in your collection.这很简单:如果您需要存储带有映射到它们的键的值,请使用 Map 接口,否则使用 List 存储可能重复的值,如果您不想在集合中使用重复的值,最后使用 Set 接口。

Here is the complete explanation http://javatutorial.net/choose-the-right-java-collection , including flowchart etc这是完整的解释http://javatutorial.net/choose-the-right-java-collection ,包括流程图等

Map地图

If choosing a Map , I made this table summarizing the features of each of the ten implementations bundled with Java 11.如果选择Map ,我制作了这个表格,总结了与 Java 11 捆绑在一起的十个实现中每一个的特性。

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

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

Which Java Collection should i use ? 我应该使用哪个Java Collection?

It depends on what problem you are trying to solve or what requirements you have. 这取决于您要解决的问题或您有哪些要求。

Examples : 例子 :

  1. Do you want the elements to be sorted while storing them ? 您希望在存储元素时对元素进行排序吗? HashSet HashSet的
  2. Do you want (Key,Value) pairs to be stored ? 你想要(Key,Value)对存储吗? HashMap HashMap中
  3. Do you want the order of elements when inserted to be preserved ? 您是否希望保留插入时元素的顺序? ArrayList, LinkedList ArrayList,LinkedList
  4. Do you want the Keys in (Key,Value) Pair to be sorted ? 您想要对(键,值)对中的键进行排序吗? - strong text - 强文
  5. Do you want to implement a Stack to solve your problem ? 你想实现一个堆栈来解决你的问题吗? - Stack - 堆叠
  6. Do you want to have FIFO(First in First out) access ? 您想要FIFO(先进先出)访问吗? - Queue - 队列
  7. Do you want only UNIQUE elements to be stored ? 您是否只想存储UNIQUE元素? - HashSet - 哈希集
  8. Do you want to allow key as "Null" while storing (Key,Value) ? 你想在存储(Key,Value)时允许密钥为“Null”吗? - HashMap - HashMap
  9. Do you want No NULL values for (Key,Value) pair ? 你想要(Key,Value)对没有NULL值吗? HashTable 哈希表

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

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