浅谈HashMap原理,并手写HashMap并实现部分区块链特征
写在前面
最近有很多的粉丝私信我,说自己在面试的时候,老是被人问HashMap的原理,但是在实际的工作中,也只是使用HashMap,从来就没有关注过它的原来,今天博主本人,根据自己的实际经验,浅谈一下HashMap的实现原理。并附上自己根据原理,手写的MHashMap,并且还带上了部分区块链的特征。
JDK7和JDK8中的HashMap
JDK7:数组和链式结构
JDK8:数组和链式结构,红黑树
两者之间的区别就是,JDK8中加上了红黑树。
因为今天是一个HashMap的原理浅析,这里就不附带讲解红黑树,后面的博文,我会专门来讲解红黑树。
正文
现在我开始正式进入我对HashMap讲解中来。
HashMap的特征
存储结构:key,value键值对的形式
查询数据:
1,通过key进行mod(取模),获取到当前数组对应的node,
2,根据node存放的hash和key对应的hash进行比较,是否一致,如果不一致,则同当前node的下一个node进行比对。
3,还是不一致,就继续从当前比较的Node取下一个节点进行比较。
存储数据:
1,对key进行mod计算
2,将数据存放到data[mod]中去
3,如果当前的data[mod]已经有值存在了,则将当前已经存在的对象oldNode,存放到新的Node的next中去
我们定义一个数组,并给给它一个默认的长度
private final static int defaultDataLength = 16;
再创建一个指定长度的数组
private Node[] data = new Node[defaultDataLength];
这里的Node为我们自己定义的一个内部类对象
@Getter
@Setter
static class Node {
private int hashCode;
private Object key;
private Object value;
private Node next;
public static Node instance(int hashCode, Object key, Object value, Node next) {
Node node = new Node();
node.setHashCode(hashCode);
node.setKey(key);
node.setValue(value);
node.setNext(next);
return node;
}
}
它由四个元素组成,当前传入key的hash值,当前的key,当前的value及下一个对象。
完整代码
package com.moonl.jvm.utils;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Set;
public class MHashMap<K, V> {
private final static int defaultDataLength = 16;
private Node[] data = new Node[defaultDataLength];
private Integer previousHashCode = 0;
public V put(K key, V value) {
int hash = hash(key);
int mod = hashMod(key);
if (null == data[mod]) {
data[mod] = Node.instance(hash, key, value, null);
return value;
}
//旧的node缓存
Node oldNode = data[mod];
//新的key,存放到指定位置的数组中去,并将原有节点存放到next中
data[mod] = Node.instance(hash, key, value, oldNode);
return value;
}
public V get(K key) {
Node node = data[hashMod(key)];
//root node hashCode
this.previousHashCode = hash((K) ("root_" + hashMod(key)));
return findKey(node, key);
}
public V findKey(Node node, K key) {
if (null == key) {
return null;
}
if (node == null)