1 public class MyHashMap<K, V> implements IMap<K, V> {
2 static final float DEFAULT_LOAD_FACTOR = 0.75f;
3 static final int DEFAULT_CAPACITY = 16;
4
5 Entry<K, V>[] table;
6 int size;
7 /**
8 * 装载因子
9 */
10 float loadFactor;
11 /**
12 * 实际的容量
13 */
14 int threshold;
15
16 public MyHashMap() {
17 this.loadFactor = DEFAULT_LOAD_FACTOR;
18 this.threshold = (int) (DEFAULT_CAPACITY * loadFactor);
19 table = new Entry[DEFAULT_CAPACITY];
20 }
21
22 public MyHashMap(int initialCapacity, float loadFactor) {
23 /**
24 * 缺少参数检查
25 */
26 int capacity = 1;
27 while (capacity < initialCapacity) {
28 capacity <<= 1;
29 }
30 this.loadFactor = loadFactor;
31 this.threshold = (int) (capacity * loadFactor);
32 table = new Entry[capacity];
33 }
34
35 public MyHashMap(int initialCapacity) {
36 this(initialCapacity, DEFAULT_LOAD_FACTOR);
37 }
38
39 /**
40 * 算术右移,计入高位影响
41 */
42 static int hash(int h) {
43 return h ^ (h >>> 20) ^ (h >>> 12) ^ (h >>> 7) ^ (h >>> 4);
44 }
45
46 @Override
47 public V put(K k, V v) {
48 if (k == null) {
49 putForNull(v);
50 }
51 int hash = hash(k.hashCode());
52 int i = indexFor(hash, table.length);
53 for (Entry<K, V> e = table[i]; e != null; e = e.next) {
54 if (e.key.hashCode() == k.hashCode()
55 && (e.key == k || (k != null && k.equals(e.key)))) {
56 V oldValue = e.value;
57 e.value = v;
58 return oldValue;
59 }
60 }
61 addEntry(k, v, i);
62 return null;
63 }
64
65 private void addEntry(K k, V v, int index) {
66 Entry<K, V> e = new Entry<K, V>(k, v, table[index]);
67 table[index] = e;
68 if (size++ > threshold) {
69 resize(table.length * 2);
70 }
71 }
72
73 void resize(int newCapacity) {
74 Entry[] newTable = new Entry[newCapacity];
75 transfer(newTable);
76 table = newTable;
77 threshold = (int) (newCapacity * loadFactor);
78 System.out.println("resize()" + " current capacity: " + table.length);
79 }
80
81 void transfer(Entry[] newTable) {
82 for (int i = 0; i < table.length; i++) {
83 Entry<K, V> e = table[i];
84 if (e != null) {
85 /**
86 * 需要將原table置为空,方可释放内存
87 */
88 table[i] = null;
89 do {
90 Entry<K, V> next = e.next;
91 /**
92 * 重复计算hash值,效率不高
93 */
94 int index = indexFor(hash(e.key.hashCode()),
95 newTable.length);
96 e.next = newTable[index];
97 newTable[index] = e;
98 e = next;
99 } while (e != null);
100 }
101 }
102 }
103
104 private V putForNull(V value) {
105 // 未实现
106 return value;
107 }
108
109 /**
110 * 用位操作取代取余操作,前提是数组长度为2的幂次
111 */
112 private int indexFor(int hash, int length) {
113 return hash & (length - 1);
114 }
115
116 @Override
117 public V get(K k) {
118 int hash = hash(k.hashCode());
119 int index = indexFor(hash, table.length);
120 Entry<K, V> e = table[index];
121 while (e != null) {
122 if (e.key.hashCode() == k.hashCode()
123 && (e.key == k || (k != null && k.equals(e.key)))) {
124 return e.value;
125 }
126 e = e.next;
127 }
128 return null;
129 }
130
131 static class Entry<K, V> {
132 K key;
133 V value;
134 Entry<K, V> next;
135 int hash;
136
137 public Entry(K k, V v, Entry<K, V> n) {
138 key = k;
139 value = v;
140 next = n;
141 // hash = h;
142 }
143
144 public V setValue(V v) {
145 V oldValue = value;
146 value = v;
147 return oldValue;
148 }
149
150 public boolean equals(Object o) {
151 if (!(o instanceof MyHashMap.Entry)) {
152 return false;
153 }
154 Entry e = (Entry) o;
155 Object k1 = e.key;
156 Object k2 = key;
157 if (k1 == k2 || (k1 != null && k1.equals(k2))) {
158 Object v1 = e.value;
159 Object v2 = value;
160 if (v1 == v2 || (v1 != v2 && v2.equals(v2))) {
161 return true;
162 }
163 }
164 return false;
165 }
166 }
167 }