HashMap

   HashMap是映射表,基本思想是键-值(对)关联,可以使用键来查找值。一般常见的Map有HashMap,LinkedHashMap,TreeMap,WeakHashMap,ConcurrentHashMap,IdentityHashMap。

   HashMap不多说,最常见,非线程安全的。

   LinkedHashMap取得“键值对”的顺序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点;而在迭代访问时反应更快,因为它使用的链表维护内部次序。

   TreeMap基于红黑树的实现。查看“键”或“键值对”时,它们会被排序(次序由Comparable或者Comparator决定)。

   WeakHashMap弱键(weak key)映射,允许释放映射所指向的对象。如果映射之外没有引用指向某个“键”,则此“键”可以被垃圾回收器回收。

   ConcurrentHashMap一种线程安全的Map。

   IdentityHashMap使用==代替equals()对“键”进行比较的散列映射。意思是key在逻辑上可以相等,但是物理地址不能相等。

 

下面代码有助于对Map有初步的理解。

 1: class MyMap<K, V> {
 2: private Object[][] pairs;
 3: private int index;
 4:  
 5: public MyMap(int length) {
 6: pairs = new Object[length][2];
 7: }
 8:  
 9: public void put(K key, V value) {
 10: if (index >= pairs.length) {
 11: throw new ArrayIndexOutOfBoundsException();
 12: }
 13: pairs[index++] = new Object[] { key, value };
 14: }
 15:  
 16: public V get(K key) {
 17: for (int i = 0; i < index; i++) {
 18: if (key.equals(pairs[i][0])) {
 19: return (V) pairs[i][1];
 20: }
 21: }
 22: return null;
 23: }
 24: }

 

但实际上,HashMap的实现不那么简单。

 1: public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {
 2: static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//默认初始化大小16
 3: static final int MAXIMUM_CAPACITY = 1 << 30; 最大初始化大小
 4: static final float DEFAULT_LOAD_FACTOR = 0.75f; 默认加载因子
 5:  
 6: transient Node<K,V>[] table;
 7: transient Set<Map.Entry<K,V>> entrySet;
 8: transient int size; //映射的个数
 9: transient int modCount; 修改次数
 10: int threshold; 下一次扩容时的值
 11: final float loadFactor; 加载因子
 12:  
 13: //K V理解为数组对
 14: static class Node<K,V> implements Map.Entry<K,V> {
 15: final int hash;
 16: final K key;
 17: V value;
 18: Node<K,V> next;
 19:  
 20: Node(int hash, K key, V value, Node<K,V> next) {
 21: this.hash = hash;
 22: this.key = key;
 23: this.value = value;
 24: this.next = next;
 25: }
 26: public final K getKey() { return key; }
 27: public final V getValue() { return value; }
 28: public final String toString() { return key + "=" + value; }
 29: public final int hashCode() {
 30: return Objects.hashCode(key) ^ Objects.hashCode(value);
 31: }
 32: public final V setValue(V newValue) {… }
 33: public final boolean equals(Object o) { … }
 34: }
 35: ....
 36: }

    相较与MyMap,不同之处,我个人的理解有,首先HashMap的桶是用数组来定的Node<K,V>[] table,但是是根据key进行hash来确定index,即是哪个桶table[index]。其次每个桶内的元素是Node<K,V>,用链表来存储。也就是说如果由于hash值一样,在桶内是一个链表来存储多个key-value。

你可能感兴趣的:(HashMap)