????????List本身是一个接口,该接口继承自Collection接口,它有两个常用的实现子类ArrayList和LinkedList。从功能特性上来看,List是有序、可重复的单列集合,集合中的每个元素都有对应的顺序索引,我们可以通过该索引来访问指定位置上的集合元素。默认情况下,List会按元素的添加顺序给元素设置索引,第一个添加到List集合中的元素索引为0,第二个为1,后面依此类推。所以List的行为和数组几乎完全相同,它们都是有序的存储结构。另外List集合中允许有重复的元素,甚至可以有多个null值。
????????但是如果我们是使用数组来添加和删除元素,就会非常的不方便。比如从一个已有的数组{'A', 'B', 'C', 'D', 'E'}中删除索引为2的元素,这个“删除”操作实际上是把'C'后面的元素依次往前挪一个位置;而“添加”操作实际上是把指定位置以后的元素依次向后挪一个位置,腾出位置给新加入的元素。针对这两种操作,使用数组实现起来都会非常麻烦。所以在实际应用中,我们增删元素时,一般都是使用有序列表(如ArrayList),而不是使用数组。
????????Set是Java的一种集合,继承自Collection接口,主要有两个常用的实现类HashSet类和TreeSet类。
????????它没有固定的大小限制,可以动态地添加和删除元素。并且Set集合中的元素都是唯一的,不会有重复的元素,即使是null值也只能有一个。另外Set集合是无序的,不能记住元素的添加顺序,因为没有索引值,所以Set集合中的对象不会按特定的方式排序,它只是简单地把对象放到集合中。
????????从特性上来看,Set相当于是一个只存储key、不存储value的Map。我们可以把Set想象成是一个”特殊的Map“,这个Map只有key却没有value,所以我们可以用Set去除重复的元素。另外由于放入Set的元素和Map的key类似,需要正确地实现equals()和hashCode()方法,否则该元素就无法正确地放入Set。
????????Map集合是一种以键值对形式存储和操作数据的数据结构,建立了key-value之间的映射关系,常用于存储和处理复杂的数据。同时Map也是一种双列集合接口,它有多个实现类,包括HashMap、TreeMap、LinkedHashMap等,最常用的是HashMap类。其中,HashMap是按哈希算法来实现存取键对象的,这是我们开发时最常用的Map子类,而TreeMap类则可以对键对象进行排序。
????????Map集合中的每个元素,都包含了一个键(key)和一个值(value),key和value组成了键-值的映射表,我们称其为键值对。键用于唯一标识一个元素,值用于存储该元素的数据,一般情况下,这个key和value可以是任何引用类型的数据。其中,键key是无序、无下标、不重复的,最多只能有一个key为null。值value是无序、无下标、可重复的,可以有多个value为null。
????????并且这个key和value之间是单向的一对一关系,即通过指定的key,总能找到唯一的、确定的value。当我们想从Map中取出数据时,只要给出指定的key,就能取出对应的value。
List 接口实例存储的是有序的,可以重复的元素。Set 接口实例存储的是无序的,不重复的数据。
Set 检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变?<实现类有HashSet,TreeSet>。
List 和数组类似,可以动态增长,根据实际存储的数据的长度自动增长 List 的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变?<实现类有ArrayList,LinkedList,Vector>?。
- list是存储单列数据的集合,map是存储键和(key,value)}这样的双列数据的集合。
- List 中存储的数据是有顺序,并且允许重复;Map 中存储的数据是没有顺序的,其键是不能重复的,但它的值是可以有重复的。
????????map和set都是stl中的关联容器,map以键值对的形式存储,key=value组成pair,是一组映射关系。set只有值,可以认为只有一个数据,并且set中元素不可以重复且自动排序,如果需要重复则使用multiset,要说区别的话,存储的东西不一样,应用场景不一样,支持的操作也不一样,很多不同。
map和set支持快速查找和删除,一般使用RB树来实现,当然后面还有用hashtable实现的,使用rb树作为底层结构增删数据都很快,不存在内存移动也就不容易出现迭代器失效的问题,这也就是区别于vector的原因-内存移动
Map中的每一个元素包含一个键对象和值对象,它们成对出现。键对象不能重复,值对象可以重复。
Set中的对象不按特定方式排序,并且没有重复对象。但它的有些实现类能对集合中的对象按特定方式排序,例如TreeSet类,它可以按照默认排序,也可以通过实现java.util.Comparator接口来自定义排序方式。
- ArrayList的实现是基于数组,LinkedList的实现是基于双向链表。
- 对于随机访问,ArrayList优于LinkedList,ArrayList可以根据下标以O(1)时间复杂度对元素进行随机访问。而LinkedList的每一个元素都依靠地址指针和它后一个元素连接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
- 对于插入和删除操作,LinkedList优于ArrayList,因为当元素被添加到LinkedList任意位置的时候,不需要像ArrayList那样重新计算大小或者是更新索引。
- LinkedList比ArrayList更占内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。
- HashSet实现了Set接口, 仅存储对象; HashMap实现了 Map接口, 存储的是键值对.
- HashSet底层其实是用HashMap实现存储的, HashSet封装了一系列HashMap的方法. 依靠HashMap来存储元素值,(利用hashMap的key键进行存储), 而value值默认为Object对象. 所以HashSet也不允许出现重复值, 判断标准和HashMap判断标准相同, 两个元素的hashCode相等并且通过equals()方法返回true.
方法 | 初始值 | 扩容条件 | 增量 | 线程安全 | 有序无序 | 能否重复 | 查询速度 | 查找效率 | 增速度 | 删速度 | 底层实现 |
List | |||||||||||
?ArrayList | 10 | 元素个数超过容量长度 时 | 1.5倍+1 | 不安全 | 可以重复 | 可以重复 | 快 | O(1) | 慢 | 慢 | object数组 |
LinkedList | 无 | 无 | 无 | 不安全 | 可以重复 | 可以重复 | 慢 | O(n/2) | 快 | 快 | 双向链表结构 |
Set | |||||||||||
HashSet | 16 | 元素个数超过容量长度的0.75倍 时 | 2倍 | 不安全 | 无序 | 不重复 | 快 | O(1) | 快 | 快 | HashMap |
Map | |||||||||||
HashMap | 16 | 元素个数超过容量长度的0.75倍时 | 2倍 | 不安全 | 无序 | 键不可以重复,值可以重复 | 快 | O(1) | 快 | 快 | Map.Entry(双列集合) |
TreeMap | 无 | 无 | 无 | 不安全 | 有序 | ?不重复 | 快 | O(log n) | 快 | 快 | 红黑树 |
HashTable | 11 | 元素个数超过容量长度的0.75倍时 | 2倍+1 | 安全 | 无序 | 不重复 | 快 | O(1) | 快 | 快 | Hashtable.Entry数组 |