在日常开发中,我们经常使用到不同的集合,而我们经常使用的集合大概分为三类List、Map、Set。
文章源码均是在java8的环境中。
解本概念图
基本概念
Iterable
源码注释:
Implementing this interface allows an object to be the target of the "for-each loop"
(statement实现此接口允许对象成为“for-each loop”语句的目标)
迭代器,根据源码注释翻译可以理解为只要implements了该接口类,都可以通过循环的方式获取到目标对象。
Collection
Collection是单列列表集合结构容器的根接口,集合表示一组对象,对象被称为元素。实现了Collection的容器都是以单列的形式存储数据。而在java中,Collection是不提供此接口的任何实现的,调用时需要调用他的下层子接口,根据不同的业务需求选择不同的集合类型。
Map
Map是健值对(多列集合)存储的根接口,以<key,Value>的形式存储。key不能重复,如果是相同的key,在存储的时候会被替换。
List
List是实现Collection的一个可以重复存储数据的集合接口。
Set
Set是实现Collection的一个不可重复存储数据的集合接口。
衍生集合
在这里介绍的衍生集合是指实现了上文中的Map、List、Set接口的具体实现类,他们根据不同接口实现了不同存储方式的集合。
ArrayList
无序列表
LinkedList
有序列表
ConcurrentMap
一个线程安全的集合接口,实现该接口的集合都能够通过线程并发访问Map集合。
ConcurrentHashMap
实现了ConcurrentMap的现场线程安全map集合。
HashMap
线程不安全,且允许一个key为null,多个value为null。
此实现为基本操作(获取和放置)提供恒定时间性能,假设哈希函数在存储桶中正确分散元素。对集合视图进行迭代所需的时间与 HashMap 实例的“容量”(存储桶数)加上其大小(键值映射数)成正比。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或负载系数太低),这一点非常重要。
HashMap有两个关键参数:初始容量、负载因子
容量是哈希表中的存储桶数,初始容量只是创建哈希表时的容量。负载系数是哈希表在容量自动增加之前允许达到的满满程度的度量。当哈希表中的条目数超过负载因子与当前容量的乘积时,将重新哈希哈希表(即重建内部数据结构),以便哈希表中的存储桶数大约是其两倍。
作为一般规则,默认负载系数 (.75) 在时间和空间成本之间提供了很好的权衡。较高的值会减少空间开销,但会增加查找成本(反映在 HashMap 类的大多数操作中,包括 get 和 put)。在设置其初始容量时,应考虑映射中的预期条目数及其负载系数,以便最大限度地减少重新散列操作的数量。如果初始容量大于最大条目数除以负载因子,则不会发生重新哈希操作。
太小了就有可能频繁发生扩容,影响效率。太大了又浪费空间。而加载因子0.75的是为了提高空间利用率和减少查询成本的折中,0.75的话碰撞最小。
HashTable
线程安全,方法都使用synchronized修饰