實現Map接口(hash原理)
阿新 • • 發佈:2018-09-28
bubuko lin 關聯 mov += quest urn port keyset
閑來無事,就實現一個簡單的map來練練手吧!
HashMap的底層實現主要是基於數組和鏈表來實現的,HashMap中通過key的hashCode來計算hash值的,由這個hash值計算在數組中的位置,將新插入的元素放到數組的這個位置,如果新插入的元素的hash值跟這個位置上已有元素的hash值相同,就會出現hash沖突,這時候,就在該位置通過鏈表來插入新的元素。
如圖,紫色部分是hash數組,綠色部分是鏈表,是為了解決沖突而產生的。
在實現Map接口時還需要實現Entry接口,以便能取出Map中元素。
package chapter3.question5; import java.util.Map;public class SimpleEntry implements Map.Entry, Comparable { private Object key; private Object value; public SimpleEntry(Object key, Object value) { this.key = key; this.value = value; } @Override public int compareTo(Object o) { SimpleEntry simpleEntry= (SimpleEntry) o; return ((Comparable) key).compareTo(simpleEntry.key); } @Override public Object getKey() { return key; } @Override public Object getValue() { return value; } @Override public Object setValue(Object value) { Object result= this.value; this.value = value; return result; } @Override public String toString() { return key + "=" + value; } }
接下來就是Map的簡單是實現啦。
package chapter3.question5; import java.util.*; public class SimpleMap implements Map { private final static int SLOT = 999; private LinkedList[] bucket = new LinkedList[SLOT]; private int size = 0; @Override public int size() { return size; } @Override public boolean isEmpty() { return size == 0; } @Override public boolean containsKey(Object key) { int index = key.hashCode() % SLOT; if (index < 0) index = -index; if (bucket[index] == null) return false; LinkedList linkedList = bucket[index]; Iterator iterator = linkedList.iterator(); while (iterator.hasNext()) { SimpleEntry entry = (SimpleEntry) iterator.next(); if (entry.getKey().equals(key)) { return true; } } return false; } @Override public boolean containsValue(Object value) { for (int i = 0; i < SLOT; i++) { if (bucket[i] != null) { LinkedList linkedList = bucket[i]; Iterator iterator = linkedList.iterator(); while (iterator.hasNext()) { SimpleEntry entry = (SimpleEntry) iterator.next(); if (entry.getValue().equals(value)) { return true; } } } } return false; } @Override public Object get(Object key) { int index = key.hashCode() % SLOT; if (index < 0) index = -index; if (bucket[index] == null) return null; LinkedList linkedList = bucket[index]; Iterator iterator = linkedList.iterator(); while (iterator.hasNext()) { SimpleEntry entry = (SimpleEntry) iterator.next(); if (entry.getKey().equals(key)) { return entry.getValue(); } } return null; } /** * @param key * @param value * @return 此前與key關聯的值 */ @Override public Object put(Object key, Object value) { int index = key.hashCode() % SLOT; if (index < 0) index = -index; SimpleEntry entry = new SimpleEntry(key, value); Object prev = null; if (bucket[index] == null) bucket[index] = new LinkedList(); LinkedList list = bucket[index]; boolean found = false; ListIterator iterator = list.listIterator(); while (iterator.hasNext()) { SimpleEntry simpleEntry = (SimpleEntry) iterator.next(); if (simpleEntry.equals(entry)) {//一對一 found = true; prev = simpleEntry.getValue(); iterator.set(entry); break; } } if (!found) { size++; bucket[index].add(entry); } return prev; } @Override public Object remove(Object key) { SimpleEntry entry = null; int index = key.hashCode() % SLOT; if (index < 0) index = -index; if (bucket[index] == null) return null; LinkedList linkedList = bucket[index]; Iterator iterator = linkedList.iterator(); while (iterator.hasNext()) { SimpleEntry simpleEntry = (SimpleEntry) iterator.next(); if (simpleEntry.getKey().equals(key)) { entry = simpleEntry; iterator.remove(); size--; break; } } return entry; } @Override public void putAll(Map m) { Set set = m.entrySet(); for (Object object : set) { Map.Entry oo = (Map.Entry) object; put(oo.getKey(), oo.getValue()); } } @Override public void clear() { for (Object key : keySet()) { remove(key); } size = 0; } @Override public Set keySet() { Set set = new HashSet(); for (int i = 0; i < SLOT; i++) { if (bucket[i] != null) { Iterator iterator = bucket[i].iterator(); while (iterator.hasNext()) { set.add(((SimpleEntry) iterator.next()).getKey()); } } } return set; } @Override public Collection values() { List list = new ArrayList(); for (int i = 0; i < SLOT; i++) { if (bucket[i] != null) { Iterator iterator = bucket[i].iterator(); while (iterator.hasNext()) { list.add(((SimpleEntry) iterator.next()).getValue()); } } } return list; } @Override public Set<Entry> entrySet() { Set set = new HashSet(); for (int i = 0; i < SLOT; i++) { if (bucket[i] != null) { Iterator iterator = bucket[i].iterator(); while (iterator.hasNext()) { set.add(((SimpleEntry) iterator.next())); } } } return set; } @Override public int hashCode() { int j = 0; for (int i = 0; i < SLOT; i++) { if (bucket[i] != null) { Iterator iterator = bucket[i].iterator(); j += ((SimpleEntry) iterator.next()).getKey().hashCode(); } } return j; } /** * 為了測試顯示map內容 * * @return */ @Override public String toString() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < SLOT; i++) { if (bucket[i] != null) { Iterator iterator = bucket[i].iterator(); while (iterator.hasNext()) { SimpleEntry entry = (SimpleEntry) iterator.next(); stringBuilder.append(entry.getKey() + "," + entry.getValue() + "\n"); } } } return stringBuilder.toString(); } }
實現Map接口(hash原理)