1. 程式人生 > 其它 >手寫HashMap,帶註解

手寫HashMap,帶註解

技術標籤:java

程式碼不全,覺得重要的就寫下去,直接執行是執行不了的,主要是我後面懶了。。。
但是大概思路還是有的
等不懶的時候再補補

import javax.xml.soap.Node;
import java.io.Serializable;
import java.util.*;

/**
 * @author chy
 * @create 2020-12-04-15:45
 */
public class MyHashMap<K,V> extends AbstractMap<K,V>
        implements Map<K,V>, Cloneable,
Serializable { /** 預設大小*/ private int DEFAULT_SIZE = 1 << 4; /** 最大值*/ private int MAX_SIZE = 1 << 30; /** 擴容因子*/ private float DEFAULT_LOAD_FACTOR = 0.75f; /** 含量大小*/ private int size; /** 實際的擴容因子 */ private float loadFactor; /** 實際大小*/ private int threshold;
transient int modCount; /** * 存放節點的陣列 */ transient MyNode<K,V>[] table; /** * 計算hash值 * @param key * @return */ static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
/** * 建構函式 * @param initSize 初始化大小 * @param loadFactor 擴容因子 */ public MyHashMap(int initSize, float loadFactor) throws Exception { if (initSize < 0){ throw new Exception("大小不能為負數"); } if (0 >=loadFactor){ throw new Exception("大小不能為0"); } if (1 <loadFactor){ throw new Exception("大小不能大於1"); } if (initSize > this.MAX_SIZE){ initSize = this.MAX_SIZE; } this.threshold = tableSizeFor(initSize); this.loadFactor = loadFactor; } /** * */ public MyHashMap(){ this.loadFactor = DEFAULT_LOAD_FACTOR; } /** * 獲取大於等於 目標值的最小的2的冪,便於hash計算 * @param size * @return */ public int tableSizeFor(int size){ int n = size -1; n |= n>>>1; n |= n>>>2; n |= n>>>4; n |= n>>>8; //最大隻有30位,右移16夠了 n |= n>>>16; return n<0? 1 : n >= MAX_SIZE ? MAX_SIZE : n+1; } /** * 根據key跟hash獲取節點 * @param hash * @param key * @return */ final MyNode<K,V> getNode(int hash, Object key) { MyNode<K,V>[] tab; MyNode<K,V> first, e; int n; K k; //判斷table是否初始化 if ((tab = table) != null && (n = tab.length) > 0 && //獲取頭節點 (first = tab[(n - 1) & hash]) != null) { //頭節點是否是目標值 if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k)))) { return first; } //遍歷節點佇列 if ((e = first.next) != null) { do { if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) { return e; } } while ((e = e.next) != null); } } return null; } /** * 獲取value,當節點不存在返回defualtValue * @param key * @param defaultValue * @return */ @Override public V getOrDefault(Object key, V defaultValue) { MyNode<K,V> e; return (e = getNode(hash(key), key)) == null ? defaultValue : e.value; } @Override public int size() { return size; } @Override public boolean isEmpty() { return size > 0; } @Override public boolean containsKey(Object key) { return getNode(hash(key),key) != null; } @Override public boolean containsValue(Object value) { MyNode<K,V>[] table = this.table; V v; // 判斷table是否為空 if (table!=null && size >0){ //遍歷table for (int i = 0; i < table.length; ++i) { //遍歷MyNode 列表 for (MyNode<K,V> n = table[i]; n != null; n = n.next){ if ((v = n.value) == value || (value != null && value.equals(v))){ return true; } } } } return false; } @Override public V get(Object key) { MyNode<K,V> node; return (node = getNode(hash(key),key)) == null? null : node.value; } @Override public V put(K key, V value) { return putVal(hash(key),key,value); } /** * * @param hash * @param key * @param value * @return */ final V putVal(int hash, K key, V value){ MyNode<K,V>[] tab; MyNode<K,V> p; int n, i; // 如果table沒有初始化,則為table初始化 if ((tab = table) == null || (n = tab.length) == 0) { n = (tab = resize()).length; } //hash不存在,則新加入節點到對應hash if ((p = tab[i = (n - 1) & hash]) == null) { tab[i] = new MyNode(hash, key, value, null); } else { MyNode<K,V> e; K k; //key已經存在 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) { e = p; //hash 相等,key不等 } else { for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = new MyNode(hash, key, value, null); //如果大於 8(可更改),則轉換為紅黑樹 // if (binCount >= TREEIFY_THRESHOLD - 1){ // treeifyBin(tab, hash); // } // break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) { break; } p = e; } } if (e != null) { V oldValue = e.value; if ( oldValue == null) { e.value = value; } return oldValue; } } ++modCount; if (++size > threshold) { resize(); } return null; } @Override public V remove(Object key) { return null; } @Override public void putAll(Map<? extends K, ? extends V> m) { } @Override public void clear() { } @Override public Set<K> keySet() { Set<Map.Entry<K,V>> es; return (es = entrySet) == null ? (entrySet = new HashMap.EntrySet()) : es; } @Override public Collection<V> values() { return null; } @Override public Set<Map.Entry<K, V>> entrySet() { return null; } @Override public boolean equals(Object o) { return false; } @Override public int hashCode() { return 0; } class MyNode<K,V> implements Map.Entry<K,V>{ final int hash; final K key; V value; MyNode<K,V> next; MyNode(int hash, K key, V value, MyNode<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } @Override public K getKey() { return key; } @Override public V getValue() { return value; } @Override public V setValue(V value) { this.value = value; return this.value; } } public static void main(String[] args) { MyHashMap myHashMap = new MyHashMap(); System.err.println(myHashMap.DEFAULT_SIZE +" "+myHashMap.MAX_SIZE); } }