常见面试题之自我实现HashMap

面试官要你自己实现HashMap,无非就是考查对JDK中HashMap的理解。Thinking in JAVA中的 SlowHashMap就不要记了,直接参考JDK写代码吧。

HashMap以键值对的方式存储数据,数据结构可理解为“链表的数组”。通过插入元素key值的hashcode和自带的hash算法决定元素的存储位置,发生hash冲突则在此节点下拉一个二元组链表,依次比较链表中的key是否与插入元素key相同,相同则覆盖,都不同则在链表起始点插入该新元素。

 

  1 //首先是Entry类
  2 
  3 public class Entry<K,V> {
  4 
  5   final K key;//key一旦指定就不可改变
  6 
  7   V value;
  8 
  9   Entry<K,V> next;//指向下一元素的“指针”
 10 
 11   public Entry(K key, V value, Entry<K,V> next) {
 12 
 13     this.key = key;
 14 
 15     this.value = value;
 16 
 17     this.next = next;
 18 
 19   }
 20 
 21 }
 22 
 23  
 24 
 25 //这里省略了负载因子、扩容等操作,如需了解请查看JDK源码
 26 
 27 public class MyHashMap<K,V> {
 28 
 29   private static final INITIAL_CAPACITY = 16;//默认容量
 30 
 31   private int size;//
 32 
 33   private Entry<K,V>[] table;//array buffer 链表的数组
 34 
 35   public MyHashMap(int size) {
 36 
 37     this.size = size;
 38 
 39     table = new Entry[size];
 40 
 41   }
 42 
 43   public MyHashMap() {
 44 
 45     this.size = INITIAL_CAPACITY ;
 46 
 47     table = new Entry[size];
 48 
 49   }
 50 
 51    //hash求索引
 52 
 53   private int indexOf(int hashCode) {
 54 
 55     return hashCode % (size - 1) 
 56 
 57   }
 58 
 59   public V put(K key,V value) {
 60 
 61     /**
 62 
 63       JDK中的HashMap是允许插入空键,为了简化直接省略这一步骤
 64 
 65     **/
 66 
 67     if(key == null || value == null)
 68 
 69       return null;
 70 
 71     int hashCode = key.hashCode();
 72 
 73     int index = indexOf(hashCode);
 74 
 75     for(Entry<K,V> e = table[index];e!=null;e=e.next) {
 76 
 77       V oldValue;
 78 
 79       K k = e.key;
 80 
 81       if(k.hashCode() == hashCode && (k == key || k.equals(key)))  {
 82 
 83         //若key存在 返回oldValue
 84 
 85         oldValue = e.value;
 86 
 87         e.value = value;
 88 
 89         return oldValue;
 90 
 91       }
 92 
 93     }  
 94 
 95     //若key不存在,将新值插入Entry链表的最前端
 96 
 97     Entry<K,V> newEntry = new Entry<K,V>(key,value,table[index]);
 98 
 99     table[index] = newEntry;
100 
101     return null;
102 
103   }
104 
105   public V get(K key) {
106 
107     //key 为空直接返回
108 
109     if(key == null )
110 
111       return null;
112 
113     int hashCode = key.hashCode();
114 
115     int index = indexOf(hashCode);
116 
117     for(Entry<K,V> e = table[index];e!=null;e=e.next) {
118 
119       K k = e.key;
120 
121       if(k.hashCode() == hashCode && (k == key || k.equals(key)))  {
122 
123         return e.value;
124 
125       }
126 
127     }
128 
129     return null;
130 
131   }
132 
133   public V remove(K key) {
134 
135     if(key == null)
136 
137       return;
138 
139     int hashCode = key.hashCode();
140 
141     int index = indexOf(hashCode);
142 
143     Entry<K,V> e = table[index];
144 
145     Entry<K,V> prev = e;
146 
147     while(e != null) {
148 
149       Entry<K,V> next = e.next;
150 
151       K key = e.key;
152 
153       if(k.hashCode() == hashCode && (k == key || k.equals(key)))  {
154 
155          if( prev == e) // e为链表头节点
156 
157             table[index] = next;
158 
159          else
160 
161            prev.next = e.next;
162 
163          return e.value;
164 
165       }
166 
167       prev = e;
168 
169       e = next;
170 
171     }
172 
173     return null;
174 
175   }
176 
177 }

 

posted @ 2014-08-26 16:39  常山赵子龙lzq  阅读(508)  评论(2编辑  收藏  举报