手动实现一个HashMap概述
在阅读完HashMap源码之后,为加深对源码的理解,手动实现了一个简单的HashMap,自己实现的HashMap仅仅实现了HashMap的put,get值方法以及resize()方法,实现扩容
定义数据存储实体Entry
自定义一个Entry,并重写hashCode和equals方法,这个实现来源原始的HashMap
package base;
import java.util.Objects;
/**
* @time: Created in 23:03 2018/1/2
* @desc 存储实体Entry类
*/
public class Entry<K, V> {
int hash;
K key;
V value;
Entry<K, V> next;
public Entry() {
}
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
public Entry(int hash, K key, V value, Entry<K, V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof Entry) {
Entry<K, V> e = (Entry<K, V>) o;
if (Objects.equals(e.key, key) &&
Objects.equals(e.value, value)) {
return true;
} else {
return false;
}
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(key) ^ Objects.hash(value);
}
@Override
public String toString() {
return key + "=" + value;
}
}
手动实现HashMap
手动实现HashMap,利用线性哈希表存储数据,实现了其put,get方法,以及根据key计算hash值,以及扩容方法resize。源码如下:
package base;
/**
* @time: Created in 22:43 2018/1/2
* @desc 手动实现的一个简化版的HashMap,只支持put,get值,resize(扩容)功能
*/
public class HashMap<K, V> {
//哈希表的初始容量
static final int initial_capacity = 4;
//加载的因子
float load_factor = 0.75f;
//记录entry的数量
int count = 0;
Entry<K, V>[] table;
public K put(K key, V value) {
Entry<K, V> newEntry = new Entry(key, value);
int hash = hash(key);
if (table == null) {
table = new Entry[initial_capacity];
count++;
}
Entry<K, V> head = table[hash];
//执行扩容,
if (count > initial_capacity * load_factor) {
resize();
}
if (head == null) {
table[hash] = newEntry;
count++;
return key;
} else {
Entry tail = new Entry<K, V>();
if (head.next == null) {
head.next = newEntry;
} else {
do {
tail = head;
} while ((head = head.next) != null);
tail.next = newEntry;
}
count++;
return key;
}
}
public V get(K key) {
Entry<K, V> entry;
return (entry = getEntry(hash(key), key)) == null ? null : entry.value;
}
public Entry<K, V> getEntry(int hash, K key) {
Entry<K, V> entry = table[hash];
if (entry == null) {
return null;
} else if (entry != null && entry.next == null) {
return entry;
} else if (entry.next != null) {
do {
if (hash == hash(entry.key) &&
(key == entry.key || (key != null && key.equals(entry.key)))) {
return entry;
}
} while ((entry = entry.next) != null);
return entry;
}
return null;
}
public int resize() {
int newCapacity = initial_capacity << 2;
Entry[] newTable = new Entry[newCapacity];
System.arraycopy(table, 0, newTable, 0, table.length);
this.table = newTable;
return newCapacity;
}
public final int hash(K key) {
//key.hashCode可能产生负值,执行一次key.hashCode()& 0x7FFFFFFF操作,
//变为整数,这里产生hash值直接模4, 保证产生的hash值不会因扩容而产生变化
return (key == null) ? 0 : (key.hashCode() & 0x7FFFFFFF % initial_capacity);
}
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("name1", "严嵩");
map.put("name2", "高拱");
map.put("name3", "徐阶");
map.put("name4", "张居正");
map.put("name5", "申时行");
System.out.println("map当前容量:" + map.count);
System.out.println(map.get("name1"));
System.out.println(map.get("name5"));
}
}
HashMap数据存储堆栈如下:
输出结果如下:
map当前容量:6
严嵩
申时行