HashMap代碼實現

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;
public interface MyMapEntry<K, V> {
 K getKey() ;//返回與此項對應的鍵。
 
 V getValue(); //返回與此項對應的值。
 V setValue(V value); 
 
 boolean equals(Object o);//比較指定對象與此項的相等性。
// (e1.getKey()==null ? e2.getKey()==null : e1.getKey().equals(e2.getKey()))  &&
// (e1.getValue()==null ? e2.getValue()==null : e1.getValue().equals(e2.getValue()))
 
 int hashCode(); //返回此映射項的哈希碼值。
// (e.getKey()==null   ? 0 : e.getKey().hashCode()) ^
//  (e.getValue()==null ? 0 : e.getValue().hashCode())
}

 

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();
    }

}

相關文章
相關標籤/搜索