Java HashMap源代码详解

Java HashMap源代码详解

HashMap链地址法确定存储位置

  将所有关键字为同义词的记录存储在同一线性表中。假设某哈希函数产生的哈希地址在区间[0,m-1]上,则设立一个指针型向量Chain Chain Hash[m];

其每个分量的初始状态都是空指针。凡是哈希地址为i的记录都插入到头指针为ChainHash[i]的链表中。在列表中的插入位置可以在表头或表尾;也可以在中间,以保持同义词在同一线性表中按关键字有序。

  例如:已知一组关键字为(19,14,23,01,68,20,84,27,55,11,10,79),则按哈希函数H(key)=key MOD 13 和链地址法处理冲突构造所得的哈希表,如下图所示:

                           

Hash map=New HashMap();

HashMap基于散列表的实现。插入和查询“键值对”的开销是固定的。可以通过构造器设置容量capacity和负载因子load factor,以调整容器的性能。

说明:

  数据存放在数组中,但物理存储是链式存储

  数组成员成为格子,且每个格子的hash值的唯一的

  每个格子可存放hash值相同的多对K-V,每对被称为桶(每个桶是唯一的即Map存放数据不可重复)

  格子中的桶与桶之间是通过指针连接的(Map是无序的)

处理流程:

  1、创建默认初始容量16,加载因子 (0.75)

  2、通过public V put(K key, V value);先计算key的hash值,确定key所在的格子(如果为空则需要创建一个新桶存放K-V,不为空则覆盖旧桶)

  3、每次创建一个桶则size大小进行记录,并在创建新桶后进行判断size与threshold阈值变量比较,如果size>threshold则需要扩充格子容量原来的2倍。

HashMap源码

  1 package java2.util2;
  2 
  3 import java.io.IOException;
  4 import java.io.Serializable;
  5 import java.util.AbstractCollection;
  6 import java.util.AbstractSet;
  7 import java.util.Collection;
  8 import java.util.ConcurrentModificationException;
  9 import java.util.Iterator;
 10 import java.util.NoSuchElementException;
 11 import java.util.Set;
 12 /**
 13  * HashMap
 14  * @author wwl
 15  *
 16  * @param <K>
 17  * @param <V>
 18  */
 19 public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>,
 20         Cloneable, Serializable {
 21 
 22     // 系统默认初始容量,必须是2的n次幂,这是出于优化考虑的
 23     static final int DEFAULT_INITIAL_CAPACITY = 16;
 24 
 25     // 系统默认最大容量2的30次幂1073741824
 26     static final int MAXIMUM_CAPACITY = 1 << 30;
 27 
 28     // 系统默认负载因子,可在构造函数中指定
 29     static final float DEFAULT_LOAD_FACTOR = 0.75f;
 30 
 31     // 用于存储的表,长度可以调整,且必须是2的n次幂
 32     transient Entry[] table;
 33 
 34     // 当前map的key-value映射数,也就是当前size  
 35     transient int size;
 36 
 37     /**
 38      * 表示HashMap所能容纳的key-value对极限,如果存储的size数大于了threshold,则需要扩容了
 39      * 阈值 
 40      * @serial
 41      */
 42     int threshold;
 43 
 44     /**
 45      * 哈希表的负载因子  
 46      * loadFactor是负载因子,增大值时可以减少Hash表(也就是Entry数组)所占用的内存空间,
 47      * 但会增加查询数据时时间的开销,而查询是最频繁的操作,减小值时会提高数据查询的性能, 但是会增大Hash表所占用的内存空间,所以一般是默认的0.75
 48      * 
 49      * @serial
 50      */
 51     final float loadFactor;
 52 
 53     /**
 54      * 用于确保使用迭代器的时候,HashMap并未进行更改 
 55      */
 56     transient volatile int modCount;
 57 
 58     /**
 59      * 构造一个带指定初始容量和加载因子的空 HashMap
 60      * 
 61      * @param initialCapacity
 62      *            初始容量
 63      * @param loadFactor
 64      *            加载因子
 65      * @throws IllegalArgumentException
 66      *             if the initial capacity is negative or the load factor is
 67      *             nonpositive
 68      */
 69     public HashMap(int initialCapacity, float loadFactor) {
 70         // 如果指定初始容量小于0,抛错 
 71         if (initialCapacity < 0)
 72             throw new IllegalArgumentException("Illegal initial capacity: "
 73                     + initialCapacity);
 74         // 如果初始容量大于系统默认最大容量,则初始容量为最大容量 
 75         if (initialCapacity > MAXIMUM_CAPACITY)
 76             initialCapacity = MAXIMUM_CAPACITY;
 77         // 如果loadFactor小于0,或loadFactor是NaN,则抛错  
 78         if (loadFactor <= 0 || Float.isNaN(loadFactor))
 79             throw new IllegalArgumentException("Illegal load factor: "
 80                     + loadFactor);
 81         // 寻找一个2的k次幂capacity恰好大于initialCapacity
 82         int capacity = 1;
 83         while (capacity < initialCapacity)
 84             // 计算出大于initialCapacity的最小的2的n次方值
 85             capacity <<= 1;
 86 
 87         this.loadFactor = loadFactor;
 88         threshold = (int) (capacity * loadFactor);// 设置容量极限
 89         // 创建一个capacity长度的数组用于保存数据
 90         table = new Entry[capacity];
 91         init();
 92     }
 93 
 94     /**
 95      * 构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap
 96      * 
 97      * @param initialCapacity
 98      *            初始容量
 99      * @throws IllegalArgumentException
100      *             if the initial capacity is negative.
101      */
102     public HashMap(int initialCapacity) {
103         this(initialCapacity, DEFAULT_LOAD_FACTOR);
104     }
105 
106     /**
107      * 构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap
108      */
109     public HashMap() {
110         this.loadFactor = DEFAULT_LOAD_FACTOR;
111         threshold = (int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
112         table = new Entry[DEFAULT_INITIAL_CAPACITY];
113         init();
114     }
115 
116     /**
117      * 构造一个映射关系与指定 Map 相同的新 HashMap
118      * 
119      */
120     public HashMap(Map<? extends K, ? extends V> m) {
121         this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
122                 DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
123         putAllForCreate(m);
124     }
125     /**
126      * 初始化
127      */
128     void init() {
129     }
130 
131     /**
132      * HashMap的哈希函数
133      * 预处理hash值,避免较差的离散hash序列
134      * @param h
135      * @return
136      */
137     static int hash(int h) {
138         h ^= (h >>> 20) ^ (h >>> 12);
139         return h ^ (h >>> 7) ^ (h >>> 4);
140     }
141 
142     /**
143      *  返回对应hash值得索引
144      *  根据key的hash值获取哈希地址
145      * @param h
146      * @param length
147      * @return
148      */
149     static int indexFor(int h, int length) {
150         //由于length是2的n次幂,所以h & (length-1)相当于h % length
151         return h & (length - 1);
152     }
153 
154     /**
155      * 返回当前map的key-value映射数,也就是当前size
156      */
157     public int size() {
158         return size;
159     }
160     /**
161      * 该HashMap是否是空的,如果size为0,则为空
162      */
163     public boolean isEmpty() {
164         return size == 0;
165     }
166     /**
167      * 返回指定键所映射的值;如果对于该键来说,此映射不包含任何映射关系,则返回 null
168      * 先根据输入的key计算hash值,得出index,找到对应数组节点,在节点内的链表结构中遍历寻找所求数据
169      */
170     public V get(Object key) {
171         if (key == null)
172             return getForNullKey();
173         int hash = hash(key.hashCode());
174         // 得到对应的hash值的桶,如果这个桶不是,就通过next获取下一个桶
175         for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
176             Object k;
177             if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
178                 return e.value;
179         }
180         return null;
181     }
182     /**
183      * 如果要得到key为null的值,则通过这个获取
184      * @return
185      */
186     private V getForNullKey() {
187         for (Entry<K, V> e = table[0]; e != null; e = e.next) {
188             if (e.key == null)
189                 return e.value;
190         }
191         return null;
192     }
193 
194     /**
195      * 如果此映射包含对于指定键的映射关系,则返回 true
196      */
197     public boolean containsKey(Object key) {
198         return getEntry(key) != null;
199     }
200 
201     /**
202      * 通过key获取一个value 
203      */
204     final Entry<K, V> getEntry(Object key) {
205         // 如果key为null,则hash为0,否则用hash函数预处理
206         int hash = (key == null) ? 0 : hash(key.hashCode());
207         // 先得到对应的hash值的桶,再比较key值如果这个桶不是,就通过next获取下一个桶
208         for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
209             Object k;
210             if (e.hash == hash
211                     && ((k = e.key) == key || (key != null && key.equals(k))))
212                 return e;
213         }
214         return null;
215     }
216 
217     /**
218      * 存放K-V
219      * 采用链地址法
220      * 哈希值[0,m-1],先计算hash根据哈希存放到对应hash值桶中,可以存放多个相同的hash
221      * 在此映射中关联指定值与指定键。如果该映射以前包含了一个该键的映射关系,则旧值被替换
222      */
223     public V put(K key, V value) {
224         if (key == null)
225             return putForNullKey(value);
226         int hash = hash(key.hashCode());
227         int i = indexFor(hash, table.length);
228         // 先得到对应的hash值的格子,判断该hash值的格子中下是否已经存储数据,若不为空则已存在,则新数据需要通过next获取下一个桶
229         for (Entry<K, V> e = table[i]; e != null; e = e.next) {
230             Object k;
231             // 如果hash相同并且key相同 ,则旧值被替换
232             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
233                 V oldValue = e.value;
234                 e.value = value;
235                 e.recordAccess(this);
236                 return oldValue;
237             }
238         }
239 
240         modCount++;
241         addEntry(hash, key, value, i);
242         return null;
243     }
244 
245     /**
246      * 当key为空时进行存放
247      * 物理存储采用链表结构
248      */
249     private V putForNullKey(V value) {
250         for (Entry<K, V> e = table[0]; e != null; e = e.next) {
251             if (e.key == null) {
252                 V oldValue = e.value;
253                 e.value = value;
254                 e.recordAccess(this);
255                 return oldValue;
256             }
257         }
258         modCount++;
259         addEntry(0, null, value, 0);
260         return null;
261     }
262 
263     /**
264      * 检查当前已创建的桶是存在
265      */
266     private void putForCreate(K key, V value) {
267         int hash = (key == null) ? 0 : hash(key.hashCode());
268         int i = indexFor(hash, table.length);
269 
270         // 遍历所有桶  
271         for (Entry<K, V> e = table[i]; e != null; e = e.next) {
272             Object k;
273              // 如果有hash相同,且key相同,那么则不需要创建新的桶,退出
274             if (e.hash == hash
275                     && ((k = e.key) == key || (key != null && key.equals(k)))) {
276                 e.value = value;
277                 return;
278             }
279         }
280         //否则,不存在hash值桶需要创建新的桶
281         createEntry(hash, key, value, i);
282     }
283     /**
284      * 根据Map创建所有对应的桶  
285      * @param m
286      */
287     private void putAllForCreate(Map<? extends K, ? extends V> m) {
288         for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m
289                 .entrySet().iterator(); i.hasNext();) {
290             Map.Entry<? extends K, ? extends V> e = i.next();
291             putForCreate(e.getKey(), e.getValue());
292         }
293     }
294 
295     /**
296      * 根据新的容量来resize这个HashMap
297      * @param newCapacity
298      */
299     void resize(int newCapacity) {
300         Entry[] oldTable = table;
301         int oldCapacity = oldTable.length;
302         if (oldCapacity == MAXIMUM_CAPACITY) {
303             threshold = Integer.MAX_VALUE;
304             return;
305         }
306         // 根据新的容量新建一个table
307         Entry[] newTable = new Entry[newCapacity];
308         // 将table转换成newTable
309         transfer(newTable);
310         // 将table设置newTable 
311         table = newTable;
312         // 设置阈值
313         threshold = (int) (newCapacity * loadFactor);
314     }
315 
316     /**
317      * 动态扩展后,将所有格子里的桶都放到新的table中 
318      */
319     void transfer(Entry[] newTable) {
320         Entry[] src = table;
321         int newCapacity = newTable.length;
322         for (int j = 0; j < src.length; j++) {
323             Entry<K, V> e = src[j];
324             if (e != null) {
325                 src[j] = null;
326                 do {
327                     Entry<K, V> next = e.next;
328                     int i = indexFor(e.hash, newCapacity);
329                     e.next = newTable[i];
330                     newTable[i] = e;
331                     e = next;
332                 } while (e != null);
333             }
334         }
335     }
336 
337     /**
338      * 将另一个Map对象copy到当前对象
339      * 将指定映射的所有映射关系复制到此映射中,这些映射关系将替换此映射目前针对指定映射中所有键的所有映射关系  
340      */
341     public void putAll(Map<? extends K, ? extends V> m) {
342         // 需要复制多少个映射关系 
343         int numKeysToBeAdded = m.size();
344         if (numKeysToBeAdded == 0)
345             return;
346 
347         // 如果要复制的映射关系比阈值还要多
348         if (numKeysToBeAdded > threshold) {
349             // 重新计算新的容量先resize 
350             int targetCapacity = (int) (numKeysToBeAdded / loadFactor + 1);
351             if (targetCapacity > MAXIMUM_CAPACITY)
352                 targetCapacity = MAXIMUM_CAPACITY;
353             int newCapacity = table.length;
354             while (newCapacity < targetCapacity)
355                 newCapacity <<= 1;
356             if (newCapacity > table.length)
357                 resize(newCapacity);
358         }
359         // 迭代将key-value映射放进该HashMap
360         for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m
361                 .entrySet().iterator(); i.hasNext();) {
362             Map.Entry<? extends K, ? extends V> e = i.next();
363             put(e.getKey(), e.getValue());
364         }
365     }
366 
367     /**
368      * 从此映射中移除指定键的映射关系(如果存在)
369      */
370     public V remove(Object key) {
371         Entry<K, V> e = removeEntryForKey(key);
372         return (e == null ? null : e.value);
373     }
374 
375     /**
376      * 根据key删除桶,并返回对应value
377      */
378     final Entry<K, V> removeEntryForKey(Object key) {
379         int hash = (key == null) ? 0 : hash(key.hashCode());
380         int i = indexFor(hash, table.length);
381         // 找到对应的格子
382         Entry<K, V> prev = table[i];
383         Entry<K, V> e = prev;
384         // 遍历所有桶 
385         while (e != null) {
386             Entry<K, V> next = e.next;
387             Object k;
388             // 如果找到对应的桶 
389             if (e.hash == hash
390                     && ((k = e.key) == key || (key != null && key.equals(k)))) {
391                 modCount++;
392                 size--;
393                 // 如果第一个就是要删的桶
394                 if (prev == e)
395                     // 则table[i]等于下一个桶
396                     table[i] = next;
397                 else
398                     // 否则上一个桶的下一个等于下一个桶
399                     prev.next = next;
400                 e.recordRemoval(this);
401                 return e;
402             }
403             prev = e;
404             e = next;
405         }
406 
407         return e;
408     }
409 
410     /**
411      * 根据桶来删除map里的值
412      */
413     final Entry<K, V> removeMapping(Object o) {
414         // 如果o不是Map.Entry的实例,则退出返回null
415         if (!(o instanceof Map.Entry))
416             return null;
417         // 将o转成Map.Entry 
418         Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
419         Object key = entry.getKey();
420         int hash = (key == null) ? 0 : hash(key.hashCode());
421         int i = indexFor(hash, table.length);
422         Entry<K, V> prev = table[i];
423         Entry<K, V> e = prev;
424 
425         while (e != null) {
426             Entry<K, V> next = e.next;
427             if (e.hash == hash && e.equals(entry)) {
428                 modCount++;
429                 size--;
430                 if (prev == e)
431                     table[i] = next;
432                 else
433                     prev.next = next;
434                 e.recordRemoval(this);
435                 return e;
436             }
437             prev = e;
438             e = next;
439         }
440 
441         return e;
442     }
443 
444     /**
445      * 从此映射中移除所有映射关系。此调用返回后,映射将为空
446      */
447     public void clear() {
448         modCount++;
449         Entry[] tab = table;
450         // 遍历table中的所有格子,然偶后设为nul
451         for (int i = 0; i < tab.length; i++)
452             tab[i] = null;
453         size = 0;
454     }
455 
456     /**
457      * 如果此映射将一个或多个键映射到指定值,则返回 true 
458      */
459     public boolean containsValue(Object value) {
460         // 如果value为空,则返回containsNullValue函数的返回值
461         if (value == null)
462             return containsNullValue();
463 
464         Entry[] tab = table;
465         // 遍历table所有格子(链表)
466         for (int i = 0; i < tab.length; i++)
467             // 遍历链表中的每个桶
468             for (Entry e = tab[i]; e != null; e = e.next)
469                 // 如果值相同,则返回true 
470                 if (value.equals(e.value))
471                     return true;
472         return false;
473     }
474 
475     /**
476      * 对value为null的处理
477      */
478     private boolean containsNullValue() {
479         Entry[] tab = table;
480         for (int i = 0; i < tab.length; i++)
481             for (Entry e = tab[i]; e != null; e = e.next)
482                 if (e.value == null)
483                     return true;
484         return false;
485     }
486 
487     /**
488      * 返回此 HashMap 实例的浅表副本:并不复制键和值本身
489      */
490     public Object clone() {
491         HashMap<K, V> result = null;
492         try {
493             result = (HashMap<K, V>) super.clone();
494         } catch (CloneNotSupportedException e) {
495             // assert false;
496         }
497         result.table = new Entry[table.length];
498         result.entrySet = null;
499         result.modCount = 0;
500         result.size = 0;
501         result.init();
502         result.putAllForCreate(this);
503 
504         return result;
505     }
506     /**
507      * 内置class输入对象,也就是桶
508      * @author wwl
509      *
510      * @param <K>
511      * @param <V>
512      */
513     static class Entry<K, V> implements Map.Entry<K, V> {
514         final K key;
515         V value;
516         Entry<K, V> next;
517         final int hash;
518 
519         /**
520          *  构造函数
521          */
522         Entry(int h, K k, V v, Entry<K, V> n) {
523             value = v;
524             next = n;
525             key = k;
526             hash = h;
527         }
528         /**
529          * 返回key
530          */
531         public final K getKey() {
532             return key;
533         }
534         /**
535          * 返回value
536          */
537         public final V getValue() {
538             return value;
539         }
540         /**
541          * 设置value
542          */
543         public final V setValue(V newValue) {
544             V oldValue = value;
545             value = newValue;
546             return oldValue;
547         }
548         /**
549          * 是否相同,比对的是key与value
550          */
551         public final boolean equals(Object o) {
552              // 如果o不是Map.Entry的实例,那么肯定不相同了
553             if (!(o instanceof Map.Entry))
554                 return false;
555             // 将o转成Map.Entry
556             Map.Entry e = (Map.Entry) o;
557             // 得到key和value对比是否相同,相同则为true
558             Object k1 = getKey();
559             Object k2 = e.getKey();
560             if (k1 == k2 || (k1 != null && k1.equals(k2))) {
561                 Object v1 = getValue();
562                 Object v2 = e.getValue();
563                 if (v1 == v2 || (v1 != null && v1.equals(v2)))
564                     return true;
565             }
566             return false;
567         }
568 
569         public final int hashCode() {
570             return (key == null ? 0 : key.hashCode())
571                     ^ (value == null ? 0 : value.hashCode());
572         }
573 
574         public final String toString() {
575             return getKey() + "=" + getValue();
576         }
577 
578         /**
579          * 使用该方法证明该key已经在该map中
580          */
581         void recordAccess(HashMap<K, V> m) {
582         }
583 
584         /**
585          * 该方法记录该key已经被移除了
586          */
587         void recordRemoval(HashMap<K, V> m) {
588         }
589     }
590 
591     /**
592      * 添加一个新的桶来保存该key和value
593      */
594     void addEntry(int hash, K key, V value, int bucketIndex) {
595         Entry<K, V> e = table[bucketIndex];
596         table[bucketIndex] = new Entry<K, V>(hash, key, value, e);
597         if (size++ >= threshold)
598             resize(2 * table.length);
599     }
600 
601     /**
602      * 新建一个桶,该方法不需要判断是否超过阈值 
603      */
604     void createEntry(int hash, K key, V value, int bucketIndex) {
605         Entry<K, V> e = table[bucketIndex];
606         table[bucketIndex] = new Entry<K, V>(hash, key, value, e);
607         size++;
608     }
609     /**
610      * 内部class HashIterator迭代器
611      * @author wwl
612      *
613      * @param <E>
614      */
615     private abstract class HashIterator<E> implements Iterator<E> {
616         Entry<K, V> next; // 下一个桶
617         int expectedModCount; // 保护HashMap没有变更
618         int index; // 当前的索引
619         Entry<K, V> current; // 当前的桶
620 
621         HashIterator() {
622              // 保存modCount,因为如果HashMap进行了任何操作modCount都会增加,所以如果发现modCount变化了,就可以抛出失败
623             expectedModCount = modCount;
624             if (size > 0) { // 进入第一个桶 
625                 Entry[] t = table;
626                 while (index < t.length && (next = t[index++]) == null)
627                     ;
628             }
629         }
630         /**
631          * 判断有没有下一个桶 
632          */
633         @Override
634         public final boolean hasNext() {
635             return next != null;
636         }
637         /**
638          * 获取下一个桶 
639          * @return
640          */
641         final Entry<K, V> nextEntry() {
642             if (modCount != expectedModCount)
643                 throw new ConcurrentModificationException();
644             Entry<K, V> e = next;
645             // 如果next为空,抛出失败
646             if (e == null)
647                 throw new NoSuchElementException();
648             // 如果next.next为空,将next定义为下一个格子中的桶,否则为该格子的下一个桶
649             if ((next = e.next) == null) {
650                 Entry[] t = table;
651                 while (index < t.length && (next = t[index++]) == null)
652                     ;
653             }
654             current = e;
655             return e;
656         }
657         /**
658          * 删除
659          */
660         @Override
661         public void remove() {
662             // 如果当前为空,抛出
663             if (current == null)
664                 throw new IllegalStateException();
665             // modCount变化了,抛出失败
666             if (modCount != expectedModCount)
667                 throw new ConcurrentModificationException();
668             // 获得当前的key
669             Object k = current.key;
670              // 设置current为null 
671             current = null;
672             // 删除掉对应key的元素
673             HashMap.this.removeEntryForKey(k);
674             // 重置expectedModCount
675             expectedModCount = modCount;
676         }
677 
678     }
679     /**
680      * 内部class ValueIterator迭代器,重写next方法
681      * @author wwl
682      *
683      */
684     private final class ValueIterator extends HashIterator<V> {
685         @Override
686         public V next() {
687             return nextEntry().value;
688         }
689     }
690     /**
691      * 内部class KeyIterator迭代器,重写next方法
692      * @author wwl
693      *
694      */
695     private final class KeyIterator extends HashIterator<K> {
696         public K next() {
697             return nextEntry().getKey();
698         }
699     }
700     /**
701      * 内部class EntryIterator迭代器,重写next方法
702      * @author wwl
703      *
704      */
705     private final class EntryIterator extends HashIterator<Map.Entry<K, V>> {
706         public Map.Entry<K, V> next() {
707             return nextEntry();
708         }
709     }
710 
711     /**
712      * 定义对应的 iterator() 方法
713      * @return
714      */
715     Iterator<K> newKeyIterator() {
716         return new KeyIterator();
717     }
718     /**
719      * 定义对应的 iterator() 方法
720      * @return
721      */
722     Iterator<V> newValueIterator() {
723         return new ValueIterator();
724     }
725     /**
726      * 定义对应的 iterator() 方法
727      * @return
728      */
729     Iterator<Map.Entry<K, V>> newEntryIterator() {
730         return new EntryIterator();
731     }
732 
733     // Views
734 
735     private transient Set<Map.Entry<K, V>> entrySet = null;
736 
737     /**
738      * 返回此映射中所包含的键的 Set 视图
739      */
740     public Set<K> keySet() {
741         Set<K> ks = keySet;
742         return (ks != null ? ks : (keySet = new KeySet()));
743     }
744 
745     /**
746      * 内部类KeySet对象
747      * @author wwl
748      * 
749      */
750     private final class KeySet extends AbstractSet<K> {
751         public Iterator<K> iterator() {
752             return newKeyIterator();
753         }
754         
755         public int size() {
756             return size;
757         }
758 
759         public boolean contains(Object o) {
760             return containsKey(o);
761         }
762 
763         public boolean remove(Object o) {
764             return HashMap.this.removeEntryForKey(o) != null;
765         }
766 
767         public void clear() {
768             HashMap.this.clear();
769         }
770     }
771 
772     /**
773      * 返回此映射所包含的值的 Collection 视图
774      */
775     public Collection<V> values() {
776         Collection<V> vs = values;
777         return (vs != null ? vs : (values = new Values()));
778     }
779 
780     /**
781      * 内部类Values 
782      * 
783      * @author wwl
784      * 
785      */
786     private final class Values extends AbstractCollection<V> {
787         public Iterator<V> iterator() {
788             return newValueIterator();
789         }
790 
791         public int size() {
792             return size;
793         }
794 
795         public boolean contains(Object o) {
796             return containsValue(o);
797         }
798 
799         public void clear() {
800             HashMap.this.clear();
801         }
802     }
803 
804     /**
805      * 返回此映射所包含的映射关系的 Set 视图
806      */
807     public Set<Map.Entry<K, V>> entrySet() {
808         return entrySet0();
809     }
810 
811     private Set<Map.Entry<K, V>> entrySet0() {
812         Set<Map.Entry<K, V>> es = entrySet;
813         return es != null ? es : (entrySet = new EntrySet());
814     }
815 
816     /**
817      *  内部类EntrySet对象
818      * 
819      * @author wwl
820      * 
821      */
822     private final class EntrySet extends AbstractSet<Map.Entry<K, V>> {
823         public Iterator<Map.Entry<K, V>> iterator() {
824             return newEntryIterator();
825         }
826 
827         public boolean contains(Object o) {
828             if (!(o instanceof Map.Entry))
829                 return false;
830             Map.Entry<K, V> e = (Map.Entry<K, V>) o;
831             Entry<K, V> candidate = getEntry(e.getKey());
832             return candidate != null && candidate.equals(e);
833         }
834 
835         public boolean remove(Object o) {
836             return removeMapping(o) != null;
837         }
838 
839         public int size() {
840             return size;
841         }
842 
843         public void clear() {
844             HashMap.this.clear();
845         }
846     }
847 
848     /**
849      * 序列化方法
850      */
851     private void writeObject(java.io.ObjectOutputStream s) throws IOException {
852         Iterator<Map.Entry<K, V>> i = (size > 0) ? entrySet0().iterator()
853                 : null;
854 
855         s.defaultWriteObject();
856 
857         s.writeInt(table.length);
858 
859         s.writeInt(size);
860 
861         if (i != null) {
862             while (i.hasNext()) {
863                 Map.Entry<K, V> e = i.next();
864                 s.writeObject(e.getKey());
865                 s.writeObject(e.getValue());
866             }
867         }
868     }
869 
870     private static final long serialVersionUID = 362498820763181265L;
871 
872     /**
873      * 通过序列读取对象
874      */
875     private void readObject(java.io.ObjectInputStream s) throws IOException,
876             ClassNotFoundException {
877         s.defaultReadObject();
878 
879         int numBuckets = s.readInt();
880         table = new Entry[numBuckets];
881 
882         init(); 
883 
884         int size = s.readInt();
885 
886         for (int i = 0; i < size; i++) {
887             K key = (K) s.readObject();
888             V value = (V) s.readObject();
889             putForCreate(key, value);
890         }
891     }
892 
893     int capacity() {
894         return table.length;
895     }
896 
897     float loadFactor() {
898         return loadFactor;
899     }
900 }
View Code

Map源码

  1 package java2.util2;
  2 
  3 import java.util.Collection;
  4 import java.util.Set;
  5 /**
  6  * 重构Map接口
  7  * @author wwl
  8  *
  9  * @param <K>
 10  * @param <V>
 11  */
 12 public interface Map<K, V> {
 13     /**
 14      * 返回map中键值对映射关系的数量
 15      * 
 16      * @return
 17      */
 18     int size();
 19 
 20     /**
 21      * 如果此映射不包含键值的映射则返回true
 22      * 
 23      * @return
 24      */
 25     boolean isEmpty();
 26 
 27     /**
 28      * 如果此映射包含指定键的映射关系,则返回 true
 29      * 
 30      * @param key
 31      * @return
 32      */
 33     boolean containsKey(Object key);
 34 
 35     /**
 36      * 如果此映射将一个或多个键映射到指定值,则返回 true
 37      * 
 38      * @param value
 39      * @return
 40      */
 41     boolean containsValue(Object value);
 42 
 43     /**
 44      * 指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
 45      * 允许null键null值
 46      * @param key
 47      * @return
 48      */
 49     V get(Object key);
 50 
 51     /**
 52      * 存放键值对
 53      * 
 54      * @param key
 55      * @param value
 56      * @return
 57      */
 58     V put(K key, V value);
 59 
 60     /**
 61      * 以前与 key 关联的值;如果没有 key 的映射关系,则返回 null。
 62      * 
 63      * @param key
 64      * @return
 65      */
 66     V remove(Object key);
 67 
 68     /**
 69      * 从此映射中移除所有映射关系
 70      */
 71     void clear();
 72 
 73     /**
 74      * 
 75      * @param m
 76      */
 77     void putAll(Map<? extends K, ? extends V> m);
 78 
 79     /**
 80      * 返回此映射中包含的键的 Set 视图
 81      * 
 82      * @return
 83      */
 84     Set<K> keySet();
 85 
 86     /**
 87      * 此映射中包含的值的 collection 视图
 88      * @return
 89      */
 90     Collection<V> values();
 91     
 92     /**
 93      * 此映射中包含的映射关系的 set 视图
 94      * @return
 95      */
 96     Set<Map.Entry<K, V>> entrySet();
 97 
 98     interface Entry<K, V> {
 99         /**
100          * 获取key值
101          * @return
102          */
103         K getKey();
104 
105         /**
106          * 获取value值
107          * @return
108          */
109         V getValue();
110 
111         /**
112          * 设置value值
113          * @param value
114          * @return
115          */
116         V setValue(V value);
117         /**
118          * 如果指定的对象等于此映射项,则返回 true
119          * @param o
120          * @return
121          */
122         boolean equals(Object o);
123         /**
124          * 此映射的哈希码值
125          * @return
126          */
127         int hashCode();
128     }
129     
130     /**
131      * 如果指定的对象等于此映射,则返回 true
132      * @param o
133      * @return
134      */
135     boolean equals(Object o);
136     
137     /**
138      * 此映射的哈希码值
139      * @return
140      */
141     int hashCode();
142 }
View Code

AbstractMap源码

  1 package java2.util2;
  2 
  3 import java.util.AbstractCollection;
  4 import java.util.AbstractSet;
  5 import java.util.Collection;
  6 import java.util.Iterator;
  7 import java.util.Set;
  8 
  9 
 10 
 11 
 12 public abstract class AbstractMap<K,V> implements Map<K,V> {
 13     protected AbstractMap() {
 14     }
 15 
 16     @Override
 17     public void clear() {
 18         entrySet().clear();
 19     }
 20 
 21     @Override
 22     public boolean containsKey(Object key) {
 23         Iterator<Entry<K,V>> i= entrySet().iterator();
 24         if(key==null){
 25             while(i.hasNext()){
 26                 Entry<K,V> e=i.next();
 27                 if(e.getKey()==null)
 28                     return true;
 29             }
 30         }else{
 31             while(i.hasNext()){
 32                 Entry<K,V> e=i.next();
 33                 if(key.equals(e.getKey()))
 34                     return true;
 35             }
 36         }
 37         return false;
 38     }
 39 
 40     @Override
 41     public boolean containsValue(Object value) {
 42         Iterator<Entry<K,V>> i=entrySet().iterator();
 43         if(value==null){
 44             while(i.hasNext()){
 45                 Entry<K,V> e=i.next();
 46                 if(e.getValue()==null)
 47                     return true;
 48             }
 49         }else{
 50             while(i.hasNext()){
 51                 Entry<K, V> e=i.next();
 52                 if(value==e.getValue())
 53                     return true;
 54             }
 55         }
 56         return false;
 57     }
 58 
 59     @Override
 60     public abstract Set<java2.util2.Map.Entry<K, V>> entrySet();
 61 
 62     @Override
 63     //允许null键null值
 64     public V get(Object key) {
 65         Iterator<Entry<K, V>> i=entrySet().iterator();
 66         if(key==null){
 67             while(i.hasNext()){
 68                 Entry<K, V> e=i.next();
 69                 if(e.getKey()==null)
 70                     return e.getValue();
 71                 
 72             }
 73         }else{
 74             while(i.hasNext()){
 75                 Entry<K, V> e=i.next();
 76                 if(key.equals(e.getKey()))
 77                     return e.getValue();
 78             }
 79         }
 80         return null;
 81     }
 82 
 83     @Override
 84     public boolean isEmpty() {
 85         return size()==0;
 86     }
 87     //volatile也是变量修饰符,只能用来修饰变量。
 88     //volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。
 89     //而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。
 90     //即通过改变就提交实现线程同步
 91     
 92     //transient是类型修饰符,只能用来修饰字段。
 93     //在对象序列化的过程中,标记为transient的变量不会被序列化。
 94     transient volatile Set<K>        keySet = null;//此处进行定义,表示每次生成set集合都是最新的
 95     @Override
 96     public Set<K> keySet() {
 97         if(keySet==null){
 98             keySet=new AbstractSet<K>() {
 99                 @Override
100                 public Iterator<K> iterator(){
101                     return new Iterator<K>(){
102                         private Iterator<Entry<K, V>> i=entrySet().iterator();
103                         
104                         public boolean hasNext(){
105                             return i.hasNext();
106                         }
107                         public K next(){
108                             return i.next().getKey();
109                         }
110                         public void remove(){
111                             i.remove();
112                         }
113                     };
114                 }
115 
116                 @Override
117                 public int size() {
118                     return AbstractMap.this.size();
119                 }
120                 @Override
121                 public boolean contains(Object k) {
122                     return AbstractMap.this.containsKey(k);
123                 }
124             };
125         }
126         return keySet;
127     }
128 
129     @Override
130     public V put(K key, V value) {
131         throw new UnsupportedOperationException();
132     }
133 
134     @Override
135     public void putAll(Map<? extends K, ? extends V> m) {
136         for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
137             put(e.getKey(), e.getValue());
138     }
139 
140     @Override
141     public V remove(Object key) {
142         Iterator<Entry<K, V>> i=entrySet().iterator();
143         Entry<K, V> correctEntry =null;
144         if(key==null){
145             while(i.hasNext()){
146                 Entry<K, V> e=i.next();
147                 if(e.getKey()==null)
148                     correctEntry=e;//让引用指向空引用
149             }
150         }else{
151             while(correctEntry==null&&i.hasNext()){
152                 Entry<K, V> e=i.next();
153                 if(key.equals(e.getKey()))
154                     correctEntry=e;
155             }
156         }
157         return null;
158     }
159 
160     @Override
161     public int size() {
162         return entrySet().size();
163     }
164 
165     transient volatile Collection<V> values = null;
166     
167     @Override
168     public Collection<V> values() {
169         if (values == null) {
170             values = new AbstractCollection<V>() {
171             public Iterator<V> iterator() {
172                 return new Iterator<V>() {
173                 private Iterator<Entry<K,V>> i = entrySet().iterator();
174 
175                 public boolean hasNext() {
176                     return i.hasNext();
177                 }
178 
179                 public V next() {
180                     return i.next().getValue();
181                 }
182 
183                 public void remove() {
184                     i.remove();
185                 }
186                         };
187                     }
188 
189             public int size() {
190                 return AbstractMap.this.size();
191             }
192 
193             public boolean contains(Object v) {
194                 return AbstractMap.this.containsValue(v);
195             }
196             };
197         }
198         return values;
199     }
200 
201     @Override
202     public boolean equals(Object obj) {
203         if(obj==this)
204             return true;
205         if(!(obj instanceof Map))
206             return false;
207         Map<K,V> m=(Map<K, V>) obj;
208         if(m.size()!=size())
209             return false;
210         try {
211             Iterator<Entry<K,V>> i = entrySet().iterator();
212             while (i.hasNext()) {
213                 Entry<K,V> e = i.next();
214                 K key = e.getKey();
215                 V value = e.getValue();
216                 if (value == null) {
217                     if (!(m.get(key)==null && m.containsKey(key)))
218                         return false;
219                 } else {
220                     if (!value.equals(m.get(key)))
221                         return false;
222                 }
223             }
224         } catch (ClassCastException unused) {
225             return false;
226         } catch (NullPointerException unused) {
227             return false;
228         }
229 
230         return true;
231     }
232 
233     @Override
234     //所有map对象的hashcode相加
235     public int hashCode() {
236         int h = 0;
237         Iterator<Entry<K,V>> i = entrySet().iterator();
238         while (i.hasNext())
239             h += i.next().hashCode();
240         return h;
241     }
242 
243     @Override
244     public String toString() {
245         Iterator<Entry<K,V>> i = entrySet().iterator();
246         if (! i.hasNext())
247             return "{}";
248 
249         StringBuilder sb = new StringBuilder();
250         sb.append('{');
251         for (;;) {
252             Entry<K,V> e = i.next();
253             K key = e.getKey();
254             V value = e.getValue();
255             sb.append(key   == this ? "(this Map)" : key);
256             sb.append('=');
257             sb.append(value == this ? "(this Map)" : value);
258             if (! i.hasNext())
259             return sb.append('}').toString();
260             sb.append(", ");
261         }
262     }
263 
264     @Override
265     protected Object clone() throws CloneNotSupportedException {
266         AbstractMap<K,V> result = (AbstractMap<K,V>)super.clone();
267         result.keySet = null;
268         result.values = null;
269         return result;
270     }
271     
272 }
View Code

 

posted @ 2014-11-23 01:20  W&L  阅读(347)  评论(0)    收藏  举报