Map | 有序性 | 线程安全性 | 备注 |
---|---|---|---|
HashMap | 无序 | 不安全 | |
TreeMap | 有序 | 不安全 | 根据键排序,可自定义Comparator |
Hashtable | 无序 | 安全(锁全表) | 不允许null |
LinkedHashMap | 有序 | 不安全 | 根据插入/访问顺序排序,有序的HashMap |
ConcurrentHashMap | 无序 | 安全(锁一个桶) | 线程安全的HashMap |
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, Serializable
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>, Serializable
AbstractMap
-> HashMap
-> LinkedHashMap
-> TreeMap
-> ConcurrentHashMap
Dictionary
-> Hashtable
Map // size, isEmpty,containsKey, containsValue, get, put, remove, clear, keySet, entrySet等方法
-> SortedMap // comparator, subMap, headMap, tailMap, firstKey, lastKey
-> NavigableMap // 添加了搜索选项到接口
-> ConcurrentMap
如果插入的key的hashcode相同,那么这些key也会被定位到Node数组的同一个格子里。 如果同一个格子里的key不超过8个,使用链表结构存储;如果超过了8个,那么会调用treeifyBin函数,将链表转换为红黑树。
成员变量
transient Node[] table; // 存储元素的数组,第一次使用时初始化,需要时扩容,大小一定是2的指数
transient Set> entrySet; // 存放具体元素的集
transient int size; // 存放元素的大小,HashMap的大小,HashMap保存的键值对的数量,不等于table长度
transient int modCount; // 每次扩容和更改map结构的计数器
int threshold; // 临界值,当size达到threshold时,将HashMap的容量加倍。threshold的值="容量*加载因子"
final float loadFactor; // 加载因子, 默认0.75
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node next;
// more code
}
public HashMap()
public HashMap(int initialCapacity)
public HashMap(int initialCapacity, float loadFactor)
public HashMap(Map extends K, ? extends V> m) // 此时table大小初始化为m.size()/loadFactor+1
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
TreeMap是利用红黑树来实现的,实现了SortMap接口,能够对保存的记录根据键进行排序。所以一般需要排序的情况下是选择TreeMap来进行。
成员变量
private final Comparator super K> comparator;
private transient Entry root;
private transient int size = 0;
private transient int modCount = 0;
static final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry left;
Entry right;
Entry parent;
boolean color = BLACK;
// more code
}
除构造函数外,Hashtable的所有 public 方法声明中都有 synchronized关键字,效率较低,考虑线程安全性的话,建议使用其他方案,比如ConcurrentHashMap。
成员变量,与HashMap基本一致
private transient Entry,?>[] table;
private transient int count;
private int threshold;
private float loadFactor;
private transient int modCount = 0;
transient LinkedHashMap.Entry head;
transient LinkedHashMap.Entry tail;
final boolean accessOrder; // true 按照访问顺序排序(每次get后调整指针), false 按照插入顺序排序。
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry before, after;
Entry(int hash, K key, V value, Node next) {
super(hash, key, value, next);
}
}
transient volatile Node[] table; // 存储元素的数组
private transient volatile Node[] nextTable; // 下一个存储元素的数组,只在resize时非空
private transient volatile long baseCount;
private transient volatile int sizeCtl;
private transient volatile int transferIndex;
private transient volatile int cellsBusy;
private transient volatile CounterCell[] counterCells;
private transient KeySetView keySet;
private transient ValuesView values;
private transient EntrySetView entrySet;
static final Node tabAt(Node[] tab, int i) {
return (Node)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
}
static final boolean casTabAt(Node[] tab, int i, Node c, Node v) {
return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
}
static final void setTabAt(Node[] tab, int i, Node v) {
U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
}
SynchronizedMap类是定义在Collections中的一个静态内部类。它实现了Map接口,并对其中的每一个方法实现,通过synchronized关键字进行了同步控制。它的锁力度也是Map,效率比ConcurrentHashMap差,但可以接收任意Map实例,实现Map的同步。
使用示例
Map<String, Object> map1 = Collections.synchronizedMap(new HashMap<String, Object>());
Map<String, Object> map2 = Collections.synchronizedMap(new TreeMap<String, Object>());