列表、动态数组、映射、哈希表、集合等有什么区别?

20

自从我开始使用Java编程以来,我一直在使用HashMaps,但实际上我并没有真正理解这些Collections的东西。

老实说,我不确定一路使用HashMaps是否对我或生产代码最好。直到现在,我只要能够按照PHP中调用它们的方式获取所需的数据(是的,我承认您现在可能会想到任何消极的事情),其中$this_is_array['this_is_a_string_index']提供了如此方便的方法来回忆变量数组。

所以现在,我已经使用Java超过3个月,在指定的接口上工作,并想知道,为什么会有这么多(更不用说向量、抽象列表{哦,列表还有很多...})?

我的意思是,它们彼此有什么不同?

更重要的是,什么是在我的情况下使用的最佳接口?


1
阅读手册。Java中的集合大约占据了一本书的四分之一,你想在答案中告诉你所有的东西。 - foret
10个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
49
API已经很明确地说明它们之间的差异和/或关系:

Collection(集合)

集合层次结构中的根接口。 集合表示一组对象,称为其元素。 一些集合允许重复元素,而其他集合则不允许。 一些集合是有序的,而其他集合是无序的。

http://download.oracle.com/javase/6/docs/api/java/util/Collection.html

List(列表)

一个有序的集合(也称为序列)。 此接口的用户精确控制每个元素插入列表的位置。 用户可以通过它们的整数索引(在列表中的位置)访问元素,并在列表中搜索元素。

http://download.oracle.com/javase/6/docs/api/java/util/List.html

Set(集)

不包含重复元素的集合。 更正式地说,集合不包含元素对e1和e2,使得e1.equals(e2),并且最多只有一个null元素。 如其名称所示,此接口建模数学集合抽象。

http://download.oracle.com/javase/6/docs/api/java/util/Set.html

Map(映射)

将键映射到值的对象。 映射不能包含重复键; 每个键最多可以映射到一个值。

http://download.oracle.com/javase/6/docs/api/java/util/Map.html


以上内容有什么让您感到困惑的吗?如果有,请编辑您的初始问题。谢谢。


3
以上皆为接口,而像 ArrayList 和 LinkedList 这样的东西则是其实现。这些实现完全按照接口规定的行事,但如果你要比较时间和空间复杂度,你需要查看实现的文档。如果实现、速度和空间需求对你不重要,那么你可以选择任何一个。 - Niel de Wet
@nieldw,当然,但这是我个人认为OP应该开始的地方。在你清楚Set和Map之间的区别之后,再考虑要使用哪种类型的Map。 - Bart Kiers
感谢指出开始阅读的位置。我承认在没有对Java API提供的数据结构有足够了解的情况下,被迫直接跳入哈希映射中。继续阅读,为什么数组没有实现列表接口?这是否意味着它属于其他结构? - lock
1
@lock,是的,在Java中,数组有点特殊。如果你正在寻找类似于数组但实现了“List”的东西,那就选择一个“ArrayList”。 - Bart Kiers

12

常见的Java集合简介:

'Map': 'Map'是一个容器,允许存储键值对。这使得使用键快速搜索其相关联的值成为可能。在java.util包中有两个实现,'HashMap'和'TreeMap'。前者被实现为哈希表,而后者被实现为平衡二叉搜索树(因此也具有键排序的属性)。

'Set': 'Set'是一个容器,仅包含唯一元素。多次插入相同的值仍将导致'Set'仅保留其一个实例。它还提供快速操作来搜索、删除、添加、合并和计算两个集合的交集。与'Map'一样,它有两种实现,'HashSet'和'TreeSet'。

'列表': '列表'接口由'Vector'、'ArrayList'和'LinkedList'类实现。'列表'基本上是一个元素的集合,保留它们的相对顺序。您可以向其中添加/删除元素,并在任何给定位置访问单个元素。与'Map'不同,'List'项由一个int索引,该索引是它们在'List'中的位置(第一个元素位于位置0,最后一个元素位于'List.size()'-1)。'Vector'和'ArrayList'使用数组实现,而'LinkedList'则使用链表。需要注意的一点是,与php的关联数组(更像Map)不同,Java和许多其他语言中的数组实际上表示连续的内存块。数组中的元素基本上是并排放置在相邻的“插槽”上。这提供了非常快的查找和写入时间,比使用更复杂的数据结构实现的关联数组要快得多。但是,它们不能被索引为除数组内数字位置之外的任何内容,与关联数组不同。

如果想成为任何语言中有效的程序员,建议深入了解数据结构,例如数组、链表、二叉搜索树、哈希表,以及堆栈和队列,以获取每个集合的优点和性能特征。没有什么比学习这个更好的替代品。

您还可以阅读Java集合教程以帮助入门。


2
如果你可以用不同的方式来解释,那么我会给你加一分。老实说,当我阅读技术文件时,我只能理解很少的技术术语。 - lock

9

简而言之(仅考虑接口):

List - 一组值,类似于“可调整大小的数组”

Set - 不允许重复项的容器

Map - 键值对集合


2

Map和List的区别。

在Map中,你有键/值对。要访问一个值,你需要知道键。键和值之间存在一种关系,这种关系是持久存在且不是任意的。例如:一个人的DNA是唯一的(键),一个人的名字(值)或一个人的社会安全号码(键)和一个人的名字(值)之间存在着强烈的关系。

在List中,你只有值(一个人的名字),要访问它,你需要知道它在列表中的位置(索引)。但是,值在列表中的位置和它的索引之间没有永久的关系,它是任意的。


2

List — 有序的元素集合,允许重复的条目。

具体类:

ArrayList — 标准可调整大小的列表。
LinkedList — 可以轻松地从开头或结尾添加/删除。
Vector — ArrayList 的较旧的线程安全版本。
Stack — 较旧的后进先出类。


Set — 不允许重复。

具体类:

HashSet — 使用 hashcode() 查找无序元素。
TreeSet — 排序和可导航。不允许空值。


Queue — 对元素进行排序以进行处理。

具体类:

LinkedList — 可以轻松地从开头或结尾添加/删除。
ArrayDeque — 先进先出或后进先出。不允许空值。


Map — 将唯一键映射到值。

具体类:

HashMap — 使用 hashcode() 查找键。
TreeMap — 排序映射。不允许空键。
Hashtable — HashMap 的旧版本。不允许空键或值。


你的想法没错,但回答一个已经有接受答案和45个赞的九年老问题似乎有些不必要。 - daniu
1
两周前我在寻找一个简短、完整且清晰的答案,但是我没有找到。现在我分享这个答案,希望能帮助其他人如果他们还在问同样的问题。 - Rayen Rejeb

1

这是一个非常复杂的问题,需要整个大学课程来讲解数据结构。简单来说,它们在内存使用和各种操作速度方面都有权衡。

真正有益的是花些时间阅读一本关于数据结构的好书——我几乎可以保证,如果你对数据结构有了良好的理解,你的代码将显著提高。

话虽如此,根据我的Java经验,我可以给你一些快速的、临时的建议。对于大多数简单的内部事务,通常优先选择ArrayList。对于传递数据集合,通常使用简单数组。只有在存在某些逻辑原因需要特殊键对应值时,才会真正使用HashMap——我没有看到有人将其用作所有数据结构的通用工具。其他结构更为复杂,往往只在特殊情况下使用。


1

正如你所知,它们是对象的容器。阅读它们各自的API将有助于理解它们之间的差异。

既然其他人已经描述了它们在使用方面的差异,我会指向这个 link ,该链接描述了各种数据结构的复杂度。

此列表与编程语言无关,并且像往常一样,实际实现会有所不同。

了解每个结构的各种操作的复杂度是有用的,因为在现实世界中,如果您不断搜索未排序的100万元素链表中的对象,则会影响性能。表现将不是最佳的。


0
列表 vs 集合 vs 映射 1)重复性:列表允许重复元素。可以插入任意数量的重复元素到列表中,而不会影响现有值及其索引。 集合不允许重复。集合和所有实现集合接口的类都应该具有唯一的元素。 映射将元素存储为键值对。映射不允许重复键,但允许重复值。 2)空值:列表允许任意数量的空值。 集合最多允许单个空值。 映射最多只能有一个空键和任意数量的空值。 3)顺序:列表及其所有实现类都保持插入顺序。 集合不保持任何顺序;但是它的几个类按照某种顺序排序,例如LinkedHashSet按照插入顺序维护元素。 与集合类似,映射也不按顺序存储元素,但是它的几个类也是这样做的。例如,TreeMap按键的升序对映射进行排序,而LinkedHashMap按插入顺序对元素进行排序,即元素添加到LinkedHashMap的顺序。

0
List Vs Set Vs Map
1) Duplicity: List allows duplicate elements. Any number of duplicate elements can be inserted into the list without affecting the same existing values and their indexes.
Set doesn’t allow duplicates. Set and all of the classes which implements Set interface should have unique elements.
Map stored the elements as key & value pair. Map doesn’t allow duplicate keys while it allows duplicate values.

2) Null values: List allows any number of null values.
Set allows single null value at most.
Map can have single null key at most and any number of null values.

3) Order: List and all of its implementation classes maintains the insertion order.
Set doesn’t maintain any order; still few of its classes sort the elements in an order such as LinkedHashSet maintains the elements in insertion order.
Similar to Set Map also doesn’t stores the elements in an order, however few of its classes does the same. For e.g. TreeMap sorts the map in the ascending order of keys and LinkedHashMap sorts the elements in the insertion order, the order in which the elements got added to the LinkedHashMap.

-1
Java中Set、List和Map的区别 - Set、List和Map是Java集合框架中的三个重要接口。在Java集合面试中,Set、List和Map在Java中的区别是最常见的问题之一。有时候这个问题会被问成在Java中什么时候使用List、Set和Map。显然,面试官想知道你是否熟悉Java集合框架的基础知识。为了决定何时使用List、Set或Map,您需要知道这些接口以及它们提供的功能。在Java中,List提供了一个有序和索引的集合,其中可能包含重复项。Set提供了一个无序的唯一对象集合,即Set不允许重复项,而Map提供了一个基于键值对和哈希的数据结构。List、Set和Map都是Java中的接口,并且在Collection API中有许多具体的实现。ArrayList和LinkedList是两个最常用的List实现,而LinkedHashSet、TreeSet和HashSet则经常用作Set实现。在这篇Java文章中,我们将看到Map、Set和List在Java中的区别,以及学习何时使用List、Set或Map。 Java中的Set vs List vs Map 正如我所说,Set、List和Map是接口,它们定义了核心契约,例如Set契约表示它不能包含重复项。根据我们对List、Set和Map的知识,让我们在不同的度量标准上对它们进行比较。

重复对象 在Java中,List和Set接口的主要区别在于List允许重复元素,而Set不允许。所有Set的实现都遵守这一约定。Map每个Entry可以保存两个对象,即键和值,它可以包含重复的值,但键始终是唯一的。更多关于Java中List和Set数据结构之间的差异请参见此处。

顺序 List和Set之间的另一个关键区别是List是有序集合,List的约定保持插入顺序或元素顺序。Set是无序集合,你不能保证元素存储的顺序。尽管某些Set的实现,如LinkedHashSet保持顺序。SortedSet和SortedMap,如TreeSet和TreeMap通过使用Comparator或Comparable来保持排序顺序。

空元素 List允许空元素,并且你可以在List中有许多空对象,因为它也允许重复。Set只允许一个空元素,因为不允许重复,而在Map中,你可以有空值,并且最多只有一个空键。值得注意的是Hashtable不允许空键或值,但HashMap允许空值和一个空键。这也是Map接口的这两种流行实现,即HashMap与Hashtable之间的主要区别。

流行的实现

Java中List接口的最流行实现是ArrayList、LinkedList和Vector类。ArrayList更通用,提供了通过索引进行随机访问,而LinkedList更适合频繁添加和删除元素。Vector是ArrayList的同步对应项。另一方面,Set接口的最流行实现是HashSet、LinkedHashSet和TreeSet。第一个是通用Set,由HashMap支持,有关HashSet在Java中的内部工作方式的详细信息,请参见。它也不提供任何排序保证,但LinkedHashSet提供了Set接口提供的唯一性以及排序。第三个实现TreeSet也是SortedSet接口的实现,因此它按compare()或compareTo()方法指定的排序顺序保留元素。现在最后一个,Map接口的最流行实现是HashMap、LinkedHashMap、Hashtable和TreeMap。第一个是非同步通用Map实现,而Hashtable是其同步对应项,两者都不提供任何排序保证,这来自于LinkedHashMap。就像TreeSet一样,TreeMap也是一个排序数据结构,并按排序顺序保留键。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,