1.接口 Collection Set Map List Queue Stack
2.常用哪些 排序 常用方法
3.实现原理 各个Jdk版本优化
4.存储结构 链表 数组 初始化容量 扩容机制 优点
5.线程安全 线程安全实现方式
继承关系
注意List和Set继承Collection Map没有继承Collection
List
1.ArrayList
2.LinkedList
3.CopyOnWriteArrayList
ArrayList
1.内部通过数据实现
1 | transient Object[] array; |
2.扩容机制
1 | private static final int MIN_CAPACITY_INCREMENT = 12; |
3.线程不安全 多线程会出现ConcurrentModificationException异常
LinkedList
1.内部通过链表来实现
1 | transient Link<E> voidLink; |
2.扩容机制 不存在扩容问题
1 | private boolean addLastImpl(E object) { |
3.同样线程不安全 多线程会出现ConcurrentModificationException异常
4.比较ArrayList LinkedList
ArrayList 在中间插入数据比较负责 需要做拷贝工作 寻找数据比较简单 数组下标
LinkedList在任意位置插入数据比较简单 链表操作 查找数据比较复杂 遍历列表
CopyOnWriteArrayList
1.内部通过数组实现 初始化容量是0
1 | private transient volatile Object[] elements; |
2.扩容机制
不存在扩容问题 每次生成一个N+1的数组 将之前的数据拷过来 新的数据追加在后边
1 | public synchronized boolean add(E e) { Object[] newElements = new Object[elements.length + 1]; |
3.线程安全
线程安全 add addAll clear remove都是synchronized方法
Map
1.HashMap
2.HashTable
3.TreeMap
4.LinkedHashMap
5.ConcurrentHashMap
6.ConcurrentSkipListMap
HashMap
1.初始化
1 | /** |
2.Put方法
1 | /** |
3.线程不安全
HashTable
1.内部数据结构
1 | /** |
- put方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
//遇到valuse是空 跑抛出异常
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
"unchecked") (
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
//当前位置存在Hash冲突
if ((entry.hash == hash) && entry.key.equals(key)) {
遇到相等的 则替换
V old = entry.value;
entry.value = value;
return old;
}
}
//当前位置不存在Hash冲突
addEntry(hash, key, value, index);
return null;
}
private void addEntry(int hash, K key, V value, int index) {
modCount++;
Entry<?,?> tab[] = table;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
//重新计算容量
rehash();
tab = table;
hash = key.hashCode();
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
"unchecked") (
Entry<K,V> e = (Entry<K,V>) tab[index];
tab[index] = new Entry<>(hash, key, value, e);
count++;
}
3.HashMap和HashTable区别
HashMap是允许key和value为null值的,用containsValue和containsKey方法判断是否包含对应键值对;
HashTable键值对都不能为空,否则报空指针异常。
TreeMap
1.内部实现
1 | //通过红黑树实现 |
2.不存在扩容问题
3.线程不安全
LinkedHashMap
1.内部实现 继承HashMap
1 | /** |
2.put方法
1 | //put方法使用HashMap的put方法 重写了newNode方法 记录了插入顺序 |
ConcurrentHashMap
一个线程安全且高效的HashMap实现 采用了 CAS + synchronized 来保证并发安全性
1.内部实现
1 | /** |
2.put方法
1 | /** Implementation for put and putIfAbsent */ |