java源码分析之HashMap(二)

2014-11-24 11:24:54 · 作者: · 浏览: 40
DEFAULT_LOAD_FACTORY)+1的较大者,装载因子为默认值
*/
public HashMap(Map< extends K, extends V> m) {
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
putAllForCreate(m);
}
上面的构造方法中调用到了init()方法,最后一个方法还调用了putAllForCreate(Map< extends K, extends V> m)。init方法是一个空方法,里面没有任何内容。putAllForCreate看方法名就是创建的时候将传入的map全部放入新创建的对象中。该方法中还涉及到其他方法,将在后面介绍。
先看初始化table时均使用了Entry,这是HashMap的一个内部类,实现了Map接口的内部接口Entry。
下面给出Map.Entry接口及HashMap.Entry类的内容。
Map.Entry接口定义的方法
1 K getKey();//获取Key
2 V getValue();//获取Value
3 V setValue();//设置Value,至于具体返回什么要看具体实现
4 boolean equals(Object o);//定义equals方法用于判断两个Entry是否相同
5 int hashCode();//定义获取hashCode的方法
HashMap.Entry类的具体实现
1 static class Entry implements Map.Entry {
2 final K key;
3 V value;
4 Entry next;//对下一个节点的引用(看到链表的内容,结合定义的Entry数组,是不是想到了哈希表的拉链法实现?!)
5 final int hash;//哈希值
6
7 Entry(int h, K k, V v, Entry n) {
8 value = v;
9 next = n;
10 key = k;
11 hash = h;
12 }
13
14 public final K getKey() {
15 return key;
16 }
17
18 public final V getValue() {
19 return value;
20 }
21
22 public final V setValue(V newValue) {
23 V oldValue = value;
24 value = newValue;
25 return oldValue;//返回的是之前的Value
26 }
27
28 public final boolean equals(Object o) {
29 if (!(o instanceof Map.Entry))//先判断类型是否一致
30 return false;
31 Map.Entry e = (Map.Entry)o;
32 Object k1 = getKey();
33 Object k2 = e.getKey();
34 // Key相等且Value相等则两个Entry相等
35 if (k1 == k2 || (k1 != null && k1.equals(k2))) {
36 Object v1 = getValue();
37 Object v2 = e.getValue();
38 if (v1 == v2 || (v1 != null && v1.equals(v2)))
39 return true;
40 }
41 return false;
42 }
43 // hashCode是Key的hashCode和Value的hashCode的异或的结果
44 public final int hashCode() {
45 return (key==null 0 : key.hashCode()) ^
46 (value==null 0 : value.hashCode());
47 }
48 // 重写toString方法,是输出更清晰
49 public final String toString() {
50 return getKey() + "=" + getValue();
51 }
52
53 /**
54 *当调用put(k,v)方法存入键值对时,如果k已经存在,则该方法被调用(为什么没有内容?)
55 */
56 void recordAccess(HashMap m) {
57 }
58
59 /**
60 * 当Entry被从HashMap中移除时被调用(为什么没有内容?)
61 */
62 void recordRemoval(HashMap m) {
63 }
64 }
看完属性和构造方法,接着看HashMap中的其他方法,一个个分析,从最常用的put和get说起吧。
put()
1 public V put(K key, V value) {
2 if (key == null)
3 return putForNullKey(value);
4 int hash = hash(key.hashCode());
5 int i = indexFor(hash, table.length);
6 for (Entry e = table[i]; e != null; e = e.next) {
7 Object k;
8 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
9 V oldValue = e.value;
10 e.value = value;
11 e.recordAccess(this);
12 return oldValue;
13 }
14 }
15
16 modCount++;
17 addEntry(hash, key, value, i);
18 return null;
19 }
当存入的key是null的时候将调用putForNUllKey方