与javaAPI中的实现方式思想相通实现细节不同,不过更容易理解!
话不多说,直接上代码!代码中有关键部分的解释:
接口Entry<K,V>
public interface Entry<K,V> {
K getKey();
V getValue();
V setValue(V value);
}
hashMap实现类,只要实现了put和get方法
/**
* 根据hashmap底层实现,自己简单的手撸一个hashmap
*
* @author wolf
* @create 2018-06-06 14:32
*/
public class wolfHashMap<K, V> {
//default size of hashMap;桶的默认大小
static int DEFAULTSIZE = 16;
//hashMap's factor to resize 加载影子,当当前的hashmap存储的元素个数大于DEFAULTSIZE*FACTOR,就需要rehash和resize
static double FACTOR = 0.75;
//define length of elements in hashMap
int size_eles = 0;
//define arrays of story
Node<K, V>[] node;
//define the node of store in hashMap
class Node<K, V> implements Entry<K, V> {
private K key;
private V value;
Node<K, V> next;
public Node(K key, V value, Node<K, V> next) {
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) {
V result = this.value;
this.value = value;
return result;
}
}
//构造函数
public wolfHashMap() {
this.node = new Node[DEFAULTSIZE];
}
public wolfHashMap(int size, double factor) {
this.DEFAULTSIZE = size;
this.FACTOR = factor;
this.node = new Node[DEFAULTSIZE];
}
//put方法的实现
public V put(K key, V value) {
V result = null;
//添加之前看是否需要扩容,扩容的时候需要resize和rehash
if (size_eles >= DEFAULTSIZE * FACTOR)
resize(size_eles);
int index = hashCode(key);
//在添加之前还要判断添加的key是否已经存在于hash表中
Node temp = node[index];
while (temp != null) {//在这里处理相同key情况。key相同时,将value替换成原来的value,并将旧的value返回
if (temp.getKey() == key) {
result = (V) temp.getValue();
temp.value = value;
return result;
}
temp = temp.next;
}
//能到这里来说明新添加的节点与原来存储的数据都不冲突
node[index] = new Node<>(key, value, null);
node[index].next = temp;
size_eles++;
return result;
}
//get方法
public V get(K key) {
int index = hashCode(key);
Node cur = node[index];
while (cur != null) {
if (cur.getKey() == key)
return (V) cur.getValue();
cur = cur.next;
}
//找不到返回null
return null;
}
//获取存储元素的个数
public int size() {
return size_eles;
}
//扩容方法,每次在现有的容量上扩大2倍
private void resize(int size) {
Node<K, V>[] newNode = new Node[DEFAULTSIZE * 2];
DEFAULTSIZE = DEFAULTSIZE * 2;
//将原来hashmap存储的数据(Node[])从新存储到newNode中
for (int i = 0; i < node.length; i++) {//遍历诶个数组节点
Node temp = node[i];
while (temp != null) {//由于一个节点后可能存在其他链接的节点,所以需要进一步遍历每个节点
int index = hashCode((K) temp.getKey());
Node before = newNode[index];
newNode[index] = temp;
newNode[index].next = before;
temp = temp.next;
}
}
node = newNode;
}
//hash算法,简单除留余法
private int hashCode(K key) {
return key.hashCode() % DEFAULTSIZE;
}
}
测试类:
/**
* @author wolf
* @create 2018-06-06 15:52
*/
public class Test {
public static void main(String[] args) {
wolfHashMap<String,String> wolfHashMap = new wolfHashMap<>();
wolfHashMap.put("wolf", "haha");
wolfHashMap.put("wolf", "haha");
wolfHashMap.put("wolf", "haha");
wolfHashMap.put("wolf", "haha");
System.out.println(wolfHashMap.size());
wolfHashMap.put("wolf1", "haha");
System.out.println(wolfHashMap.size());
System.out.println(wolfHashMap.get("1"));
}
}