集合
一、顶层接口
- Collection
- Map
二、Collection,Map的子接口
- Collection:List、LinkedList、Vector
- Map: HashMap、TreeMap、LinkedHashMap、Set、HashTable
1、 List(有序可重复)
ArrarList
- 底层数据结构:数组
- 内存分布:连续有序的数据结构
- 优点:查询快
- 缺点:增删慢
- 安全:线程不安全
LinkedList
- 底层数据结构:链表
- 内存分布:不连续的数据结构
- 优点:查询慢
- 缺点:增删快
- 安全:线程不安全
Vector
- 底层数据结构:数组
- 内存分布:连续有序的数据结构
- 优点:查询快
- 缺点:增删慢
- 安全:线程安全
2、Set(无序不重复)
HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
- 依赖两个方法:hashCode()和equals()
LinkedHashSet
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
- 由链表保证元素有序
- 由哈希表保证元素唯一
TreeSet
底层数据结构是红黑树。(唯一,有序)
- 如何保证元素排序的呢?
自然排序
比较器排序 - 如何保证元素唯一性的呢?
根据比较的返回值是否是0来决定
二、Map
- HashMap
- HashTable
- TreeMap
- LinkedHashMap
1、 HashMap
- 线程安全
- Key,Value
- jdk1.8后的数据结构:数组、链表、红黑树
- 数组:初始化容量16,每次扩容数组长度原来的两倍
- 链表:解决哈希冲突
- 红黑树:当链表的长度大于8时,将链表转化为红黑树,提高查询效率
(1)、计算hash值
static final int hash(Object key) {
int h;
return key == null ? 0 : (h = key.hashCode()) ^ h >>> 16;
}
map拿到传入的Key值,如果Key等于null,返回0,将这个数据保存在数组的第一位,不为空就计算Hash值,返回数组的下标
- 获取获取数组下标
- 必备知识点:^(异或运算)
先将数值转换成二进制,然后进行异或运算,比如5^6,
5的二进制101
6的二进制110
相同部分取0,不同取0,结果是011
然后将二进制转换成数值
从二进制数值的最右边一次乘2的次方,想加
11+12+0+4=3
所以5^6=3; - (>>> 无符号右移)
(2)、Put
- 首先是根据Key计算出索引值
- 然后获取当前集合元素的储存情况tab
- 判断当前map集合有没有被初始化,没有初始化就初始化集合,容量16;
- 然后根据计算出来的索引值,取tab中去查询是否存在元素,不存在直接插入,存在判断key是否相同,相同就覆盖,不存在就判断数据格式是否是红黑树,是就红黑树插入,不是就链表插入,如果链表长度等于8,将链表变成红黑树