集合是用来存放数据的,大部分集合底层都是使用数组来进行实现的。但是数组有一个缺点,就是数组一旦初始化后,就无法改变数组的长度,那么我们在存放未知个数的数据的时候,数组就已经无法满足我们的需求了。
于是就有了集合,它的底层虽然是数组实现,但是却对底层数组进行了动态维护,使得集合可以动态进行扩容操作,而且提供公有的操作数组的方法,免去了使用索引下标在操作数组时而引起的各种问题。
Java集合框架结构
为什么要有集合?
集合主要有Collection和Map两种体系。
Collection
Collection是java.util包下的集合类的顶级接口,它的子类有List和Set。Java中的集合框架都是围绕这一个接口标准而设计实现的。
Map
Map是Java.util包下的集合类顶级接口,和Collection同级,它的实现类主要有HashMap,HashTable,ConcurrentHashMap。它存放的数据是key-value形式的。
List集合
List是Collection接口下的一个集合接口,是所有List类的规范接口,它的实现类主要有ArrayList,LinkedList,Vector等实现类。
- List集合存放元素有顺序,可以存放重复的元素。
ArrayList
- ArrayList是最为常用的集合之一,底层使用数组实现,线程不安全,查找效率快,增删效率慢。
- 扩容机制:ArrayList扩容后的容量为原来的容量的1.5倍。
- ArrayList在使用无参构造创建对象的时候,不会开辟数组空间,在进行第一次添加操作的时候,才进行数组空间的开辟,默认初始化值为10。
LinkedList
- LinkedList底层使用的是Node节点的链表实现,线程不安全,查找效率慢,增删效率快。
Vector
- Vector的功能和ArrayList基本相似,不过Vector是线程安全的集合,底层使用synchronized关键字进行同步。
- 扩容机制:Vector扩容后的容量为原来的容量的2倍。
List集合实现类的区别
ArrayList | Vector | LinkedList | |
相同之处 | 存放元素有顺序,元素可重复 | ||
底层实现 | 数组 | 数组 | 链表 |
是否同步 | 不同步,线程不安全 | 同步,线程安全 | 不同步,线程不安全 |
效率 | 查找快,增删慢 | 查找快,增删慢 | 查找慢,增删快 |
扩容机制 | 扩容后的容量为原来的容量的1.5倍 | 扩容后的容量为原来的容量的2倍 | 链表,不需要扩容 |
Set集合
Set接口的实现类主要有HashSet和TreeSet。
HashSet
- HashSet底层使用的是HashMap实现,元素存取无顺序,元素不可重复,可以存放null值。
TreeSet
- TreeSet底层使用的是二叉树实现。
List集合和Set集合的区别
List | Set |
---|---|
元素可重复 | 元素不可重复 |
元素存取有顺序 | 元素存取无顺序 |
Map集合
Map集合是哈希类型的集合,也就是散列表结构,用于存放key-value类型的键值对,保证key唯一性。
HashMap(重点)
- HashMap存放key-value键值对,可以存放null值 ,线程不安全。
- HashMap默认初始化容量大小为16,默认负载因子为0.75。
- HashMap第一次创建的时候不会开辟数组空间,只有第一次进行put操作的时候,才会进行数组空间的开辟。
- HashMap的链表长度大于等于8,会转换为红黑树,红黑树长度小于等于6,会转换为链表。
- HashMap在扩容的时候,JDK7及以前的版本先扩容再插入元素,JDK8之后先插入元素再扩容。
- HashMap在JDK7及以前版本的时候,使用数组+链表实现,JDK8之后使用数组+链表+红黑树实现。
- HashMap在JDK7及以前版本,在发生哈希碰撞的时候,使用头插法插入元素,JDK8之后,使用尾插法插入元素。
HashTable
- HashTable的功能基本和HashMap相似,不过HashTable是线程安全的,使用了synchronized关键字进行同步,HashTable的key-value值不可以存放null值。
ConcurrentHashMap
- ConcurrentHashMap是HashTable的替代类,扩展性和性能比HashTable较好,线程安全。
HashMap和HashTable的区别
HashMap | HashTable |
---|---|
JDK1.2出现的集合类 | JDK1.1出现的集合类 |
线程不安全,不同步 | 线程安全,底层使用synchronized关键字同步 |
key和value可以存放null值 | key和value不可以存放null值 |
HashMap不同版本的区别
JDK7及以前的版本 | JDK8 | |
---|---|---|
底层实现 | 数组+链表 | 数组+链表+红黑树 |
扩容 | 先扩容再插入键值对 | 先插入键值对,再进行扩容 |
链表插入的方法 | 头插法 | 尾插法 |