package collections; java
import java.util.Collection;
import java.util.Set; 算法
//類的範型參數,文件名稱沒有 範型參數描述。
//開放定址法(線性探測再散列,二次探測再散列,僞隨機探測再散列) 再哈希法 鏈地址法 創建一個公共溢出區 編程
public interface MyMap<K, V> {
boolean isEmpty(); //若是此映射未包含鍵-值映射關係,則返回 true。
int size() ;//返回此映射中的鍵-值映射關係數。
V put(K key, V value); //將指定的值與此映射中的指定鍵關聯(可選操做)。
void putAll(MyMap<? extends K,? extends V> m) ;//從指定映射中將全部映射關係複製到此映射中(可選操做)。
boolean containsKey(K key) ; //若是此映射包含指定鍵的映射關係,則返回 true。
boolean containsValue(V value);//若是此映射將一個或多個鍵映射到指定值,則返回 true。
//三種集合視圖 和單個值對象
V get(K key); //返回指定鍵所映射的值;若是此映射不包含該鍵的映射關係,則返回 null。
Set<K> keySet(); //返回此映射中包含的鍵的 Set 視圖。
Collection<V> values(); //返回此映射中包含的值的 Collection 視圖。
Set<MyMapEntry<K,V>> entrySet() ;//返回此映射中包含的映射關係的 Set 視圖。
V remove(K key); //若是存在一個鍵的映射關係,則將其今後映射中移除(可選操做)。
void clear(); //今後映射中移除全部映射關係(可選操做)。
boolean equals(Object o) ;//比較指定的對象與此映射是否相等。
int hashCode(); //返回此映射的哈希碼值。
} 數組
package collections; 函數
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
// Map 接口提供三種collection 視圖,容許以鍵集、值集或鍵-值映射關係集的形式查看某個映射的內容。
//全部通用的映射實現類應該提供兩個「標準的」構造方法:一個 void(無參數)構造方法,用於建立空映射;
//一個是帶有單個 Map 類型參數的構造方法,用於建立一個與其參數具備相同鍵-值映射關係的新映射。 ui
//HashMap其實也是一個線性的數組實現的,因此能夠理解爲其存儲數據的容器就是一個線性數組。//打個比方, 第一個鍵值對A進來,經過計算其key的hash獲得的index=0,記作:Entry[0] = A。
//一會後又進來一個鍵值對B,經過計算其index也等於0,如今怎麼辦?HashMap會這樣作:B.next = A,Entry[0] = B,
//若是又進來C,index也等於0,那麼C.next = B,Entry[0] = C;這樣咱們發現index=0的地方其實存取了A,B,C三個鍵值對,他們經過next這個屬性連接在一塊兒。 spa
public class MyHashMap<K,V> implements MyMap<K,V>,Cloneable, Serializable { .net
private static final long serialVersionUID = 364045005810968434L;
private MyMapEntryImpl[] table;//Entry數組表
static final int DEFAULT_INITIAL_CAPACITY = 16;//默認數組長度
private int size; code
// 構造函數
public MyHashMap() {
table = new MyMapEntryImpl[DEFAULT_INITIAL_CAPACITY];
size = DEFAULT_INITIAL_CAPACITY;
}
MyHashMap(int initialCapacity){};//構造一個帶指定初始容量和默認加載因子 (0.75) 的空 HashMap。
MyHashMap(int initialCapacity, float loadFactor){} //構造一個帶指定初始容量和加載因子的空 HashMap。
MyHashMap(MyHashMap<? extends K,? extends V> m){} //構造一個映射關係與指定 Map 相同的新 HashMap。 對象
//獲取數組長度
public int getSize() {
return size;
}
// 求index 列表的 哈希索引位置
static int indexFor(int h, int length) {
return h % (length - 1);
}
//獲取元素
public V get(K key) {
if (key == null)
return null;
int hash = key.hashCode();// key的哈希值
int index = indexFor(hash, table.length);// 求key在數組中的下標
for (MyMapEntryImpl<K, V> e = table[index]; e != null; e = e.next) {
K k = e.key;
//hashcode 相同 及 equals也相同
if (e.key.hashCode() == hash && (k == key || key.equals(k)))
return e.value;
}
return null;
}
// 添加元素 有的話 返回原來舊的值《
public V put(K key, V value) {
//容許null null 鍵值對
if (key == null)
return null;
int hash = key.hashCode();
int index = indexFor(hash, table.length);
// 若是添加的key已經存在,那麼只須要修改value值便可
for (MyMapEntryImpl<K, V> e = table[index]; e != null; e = e.next) {
K k = e.key;
if (k.hashCode() == hash && (k == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
return oldValue;// 原來的value值
}
}
// 若是key值不存在,那麼須要添加
MyMapEntryImpl<K, V> e = table[index];// 獲取當前數組中的e
table[index] = new MyMapEntryImpl<K, V>(key, value, e);// 新建一個Entry,並將其指向原先的e
return null;
}
public void clear() {
// TODO Auto-generated method stub
}
public boolean containsKey(Object key) {
// TODO Auto-generated method stub
return false;
}
public boolean containsValue(Object value) {
// TODO Auto-generated method stub
return false;
}
public Set entrySet() {
// TODO Auto-generated method stub
return null;
}
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
public Set keySet() {
// TODO Auto-generated method stub
return null;
}
public void putAll(MyMap m) {
// TODO Auto-generated method stub
}
public V remove(K key) {
// TODO Auto-generated method stub
return null;
}
public int size() {
// TODO Auto-generated method stub
return 0;
}
public Collection values() {
// TODO Auto-generated method stub
return null;
}
}
package collections;
/**
* hashMap 由於不能修改 鍵值 因此定義爲 final
* @author wangyuehui
* @param <K>
* @param <V>
*/
public class MyMapEntryImpl<K, V> implements MyMapEntry<K, V> {
final K key;
V value;
MyMapEntryImpl<K,V> next;//下一個結點
//構造函數
public MyMapEntryImpl(K k, V v, MyMapEntryImpl<K,V> n) {
key = k;
value = v;
next = n;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
@SuppressWarnings("unchecked")
public final boolean equals(Object o) {
//首先判斷 是否是當前對象
//編程技巧 instanceof 回車 自動構建代碼塊
if (!(o instanceof MyMapEntryImpl))
return false;
MyMapEntryImpl<K, V> e = (MyMapEntryImpl<K, V>)o;
//先判斷鍵,再判斷值 《自身對象,和 其餘對象的比較》
K k1 = getKey();
K k2 = e.getKey();
//這個時候有 null值 及 null鍵的邏輯判斷
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
V v1 = getValue();
V v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
public final int hashCode() {
//括號加錯了,算法的實現邏輯
return (key==null ? 0 : key.hashCode()) ^ (value==null ? 0 : value.hashCode());
}
public final String toString() {
return getKey() + "=" + getValue();
}
}