/***
-
手写hashmap
-
@param
-
@param
*/
public class MbHMap<K, V> implements MbMap<K, V> {public static int defultLength = 16;
//定义一个HashMap骨架数组
public Entry<K, V>[] table = null;//扩容标准 数组总长度/以使用数组长度
private static double defultAddSizeFactor = 0.75;
//以使用的数组
private int userSize;public MbHMap() {
this(defultLength, defultAddSizeFactor);
}//数组长度 ,扩容标准
public MbHMap(int length, double defultAddSizeFactor) {
if (length < 0) {
throw new IllegalArgumentException(“数组参数不能为负数”);
}if (defultAddSizeFactor <= 0 || Double.isNaN(defultAddSizeFactor)) { throw new IllegalArgumentException("扩容标注必须大于0"); } this.defultLength = length; this.defultAddSizeFactor = defultAddSizeFactor; table = new Entry[length];
}
/***
-
快速存储
-
@param k
-
@param v
-
@return
*/
public V put(K k, V v) {
if (userSize > defultAddSizeFactor * defultLength) {
//扩容
up2Size();
}
//通过key来找到存储位置
int index = getIndex(k, table.length);
//拿到对应entry值
Entry<K, V> entry = table[index];if (entry == null) {
table[index] = new Entry(k, v, null);
userSize++;
} else { //Entry有值时
table[index] = new Entry(k, v, entry);
}
return entry.getValue();
}
//扩容2倍
private void up2Size() {
// 16 * 2
Entry<K, V>[] newTable = new Entry[2 * defultLength];//将散列的数组再次散列 againHash(newTable);
}
private void againHash(Entry<K, V>[] newTable) {
//将数组对象封装List
List<Entry<K, V>> entrylist = new ArrayList<Entry<K, V>>();for (int i = 0; i < table.length; i++) { if (table[i] == null) { continue; } fundEntryByNext(table[i], entrylist); } if (entrylist.size() > 0) { userSize = 0; defultLength = 2 * defultLength; table = newTable; //将最上面一个entry对象 next情况 for (Entry<K, V> entry : entrylist) { if (entry.next != null) { entry.next = null; } put(entry.getKey(), entry.getValue()); } }
}
//根据entry 选择下一个entry
private void fundEntryByNext(Entry<K, V> entry, List<Entry<K, V>> entrylist) {
if (entry != null && entry.next != null) {
entrylist.add(entry);
//递归加集合中
fundEntryByNext(entry.next, entrylist);
} else {
entrylist.add(entry);
}}
//通过数组长度 ,和k的位置 来找到Entry 存放位置
public int getIndex(K k, int length) {int m = length - 1; int index = hash(k.hashCode()) & m; //三木运算符保证数据正确 return index >= 0 ? index : -index;
}
//找到自己的Hash算法
private int hash(int hashCode) {
hashCode = hashCode ^ ((hashCode >>> 20)) ^ (hashCode >>> 12);return hashCode ^ ((hashCode >>> 7)) ^ (hashCode >>> 4);
}
/***
-
快取
-
@param k
-
@return
*/
@Override
public V get(K k) {int index = getIndex(k, table.length);
if (table[index] == null) {
throw new NullPointerException(“空指针异常”);
}return findValueByEqualKey(k, table[index]);
}
/**
-
通过key找到实体对象
-
@param k
-
@param entry
-
@return
*/
private V findValueByEqualKey(K k, Entry<K, V> entry) {if (k == entry.getKey() || k.equals(entry.getKey())) {
return entry.getValue();
} else if (entry.next != null) {
return findValueByEqualKey(k, entry.next);
}return null;
}
/**
-
内部类
-
@param
-
@param
*/
class Entry<K, V> implements MbMap.Entry<K, V> {K k;
V v;
Entry<K, V> next; //指向被this积压的entry对象public Entry(K k, V v, Entry<K, V> next) {
this.k = k;
this.v = v;
this.next = next;
}@Override
public K getKey() {
return k;
}@Override
public V getValue() {
return v;
}
}
public int userSize() {
return userSize;
}public static int getDefultLength() {
return defultLength;
}public static void setDefultLength(int defultLength) {
MbHMap.defultLength = defultLength;
}public Entry<K, V>[] getTable() {
return table;
}public void setTable(Entry<K, V>[] table) {
this.table = table;
}public static double getDefultAddSizeFactor() {
return defultAddSizeFactor;
}public static void setDefultAddSizeFactor(double defultAddSizeFactor) {
MbHMap.defultAddSizeFactor = defultAddSizeFactor;
}public int getUserSize() {
return userSize;
}public void setUserSize(int userSize) {
this.userSize = userSize;
}
} -