正常狀況下,Map的key和Value均可以用數組實現,一邊ArrayList是key的keys,另外一邊是ArrayList value的values。 java
經過key獲取value的方式是這樣的values.get(keys.indexOf(key)). 數組
然而,數組的長度是有限的。不符合map能夠無限放入元素的要求。因此要對這個數組進行特殊的要求。 ide
那就是同一個數組的index能夠存放多個值,只是這些相同index的hascode值不一樣,這樣就能把他們卻別開了。同時也就實現無限個元素要求了(用數組實現主要是性能的優點)。那麼要肯定value就要計算hascode和數組下標。 性能
數組不直接執行value的值,而是用equals()方法線性的查找;正常狀況下這樣的查找方式也會慢,可是隻要hascode方法設計的合理,每一個插槽將會只有少許的value.這樣查找也就快不少; this
import java.util.Map; public class MapEntry<K,V> implements Map.Entry<K, V> { private K key; private V value; public MapEntry(K key, V value) { this.key = key; this.value = value; } @Override public K getKey() { return key; } @Override public V getValue() { return value; } @Override public V setValue(V value) { V result = this.value; this.value =value; return result; } @Override public int hashCode() { return (key == null ? 0:key.hashCode())^(value == null ? 0: value.hashCode()); } @Override public boolean equals(Object obj) { if(!(obj instanceof MapEntry)) { return false; } MapEntry me = (MapEntry)obj; return (key ==null ? me.getKey() == null : key.equals(me.getKey())) && (value == null ? me.getValue()==null : value.equals(me.getValue())); } @Override public String toString() { return key+"="+value; } }
import java.util.AbstractMap; import java.util.HashSet; import java.util.LinkedList; import java.util.ListIterator; import java.util.Map; import java.util.Set; public class SimpleHashMap<K,V> extends AbstractMap<K, V> { static final int SIZE = 997; /**集合類型數組,數組的每一個元素都是一個List集合類型**/ LinkedList<MapEntry<K, V>>[] buckets = new LinkedList[SIZE]; public V put(K key, V value) { V oldValueV = null; /**根據hascode對數組長度求模,計算得出應該放入數組的index位置**/ int index = Math.abs(key.hashCode())%SIZE; if(buckets[index] == null) { /**若是該下標下尚未集合,則建立**/ buckets[index] = new LinkedList<MapEntry<K, V>>(); } LinkedList<MapEntry<K, V>> bucket = buckets[index]; /**把傳進來的key和value封裝爲MapEntry類型**/ MapEntry<K, V> pair = new MapEntry<K, V>(key, value); /**假設在該數組index下的機會裏找不到與pair對應的值**/ boolean found = false; ListIterator<MapEntry<K, V>> it = bucket.listIterator(); while(it.hasNext()) { MapEntry<K, V> iPair = it.next(); if(iPair.getKey().equals(key)) { /**若是已經存在,則替換掉**/ oldValueV = iPair.getValue(); it.set(pair); found = true; break; } } if(!found) { /**若是不存在,則把封裝後的MapEntry對象加入的集合中**/ buckets[index].add(pair); } return oldValueV; } public V ge(Object key) { /**已一樣的方式計算出應該的index**/ int index = Math.abs(key.hashCode())%SIZE; if(buckets[index]==null) { /**對應的index裏沒有機會**/ return null; } for(MapEntry<K, V> iPair : buckets[index]) { if(iPair.getKey().equals(key)) { /**對該index下的機會進行查找,比較MapEntr的key值**/ return iPair.getValue(); } } return null; } @Override public Set<Map.Entry<K, V>> entrySet() { Set<Map.Entry<K, V>> set = new HashSet<Map.Entry<K,V>>(); for(LinkedList<MapEntry<K, V>> bucket : buckets) { if(bucket == null) continue; for(MapEntry<K, V> mpair : bucket) { /**用2個for循環,遍歷這個二維的集合,把遍歷到的每一個值放到Set裏**/ set.add(mpair); } } return set; } public static void main(String[] args) { SimpleHashMap<String, String> mMap = new SimpleHashMap<String,String>(); mMap.put("YYY", "yyy"); mMap.put("QQQ", "qqq"); mMap.put("AAA", "aaa"); mMap.put("GGG", "ggg"); System.out.println(mMap); System.out.println(mMap.get("GGG")); System.out.println(mMap.entrySet()); } }
摘自thinking in java spa