package com.mollen.resource.map;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
/**
* IHashMap
*
* @author 阔皮大师.
* @created 2022-04-27 23:56
*/
public class IHashMap<K,V> {
// 初始化数组长度
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
// 数组最大长度
static final int MAXIMUM_CAPACITY = 1 << 30;
// 链表转树阈值
static final int TREEIFY_THRESHOLD = 8;
// 扩容系数
static final float DEFAULT_LOAD_FACTOR = 0.75f;
// 树转链表阈值
static final int UNTREEIFY_THRESHOLD = 6;
// 树化最小容量
static final int MIN_TREEIFY_CAPACITY = 64;
// Hash表
transient Node<K,V>[] table;
// 上一次扩容之后的容量阈值
int threshold;
/**
* 定义Node【数组元素】
*/
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
// 链表下一个节点,默认赋null,有新元素进来替换掉null
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final String toString() {
return key + "=" + value;
}
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (o == this) {
return true;
}
if (o instanceof Map.Entry) {
Map.Entry<K,V> entry = (Map.Entry<K,V>)o;
if (Objects.equals(key, entry.getKey()) && Objects.equals(value, entry.getValue())) {
return true;
}
}
return false;
}
}
/**
* putVal: 插入数据
*/
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
// 定义数组大小
Node<K, V>[] tab = table;
// 尾部节点
Node<K, V> p;
// 定义数组长度、元素索引
int n;
int i;
// 数组为空,初始化数组
n = tab.length;
if (tab == null || n == 0) {
tab = resize();
n = tab.length;
}
// 索引位置没有节点,创建一个节点
p = tab[i = (n - 1) & hash];
if (p == null) {
tab[i] = new Node(hash, key, value, null);
}
// 索引位置有节点
else {
// 定义一个节点,用于给当前节点赋值
Node<K,V> e;
K k;
// 插入元素的hash值和key相等/key值相等
k = p.key;
if (p.hash == hash && Objects.equals(k, key)) {
e = p;
}
// 尾节点是树节点
else if (p instanceof TreeNode) {
// e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
}
// 尾节点为链表节点
else {
// 循环遍历链表直到找到为空(next == null)的节点把需要插入的节点赋值给他
for (int binCount = 0; ; ++binCount) {
// 尾结点空的
e = p.next;
if (e == null) {
// 先给尾节点赋个值
p.next = new Node<>(hash, key, value, null);
// 满足条件树形转换.
if (binCount >= TREEIFY_THRESHOLD - 1) {
// treeifyBin(tab, hash);
}
break;
}
// 用于赋值的节点k和需要插入的节点k是同一个k说明插值已经完成了
k = e.key;
if (e.hash == hash && (Objects.equals(k, key))) {
break;
}
p = e;
}
}
// key处理完了,位置找好了,坐下来喝杯茶吧
if (e != null) {
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null) {
e.value = value;
}
// 预留方法,hashMap未做实现,详情可以去看看LinkedHashMap
// afterNodeAccess(e);
return oldValue;
}
}
return null;
}
/**
* 数组初始化/扩容.
*/
final Node<K,V>[] resize() {
// 原hashTable数组
Node<K,V>[] oldTab = table;
// 原hashTable数组长度
int oldCap = (oldTab == null) ? 0 : oldTab.length;
// 扩容之前的容量阈值
int oldThr = threshold;
// 扩容之后的数组长度
int newCap = 0;
// 扩容之后的容量阈值
int newThr = 0;
// 判断原数组长度0
if (oldCap > 0) {
newCap = oldCap << 1;
// 超过扩容最大值(1<<30)不扩容
if (oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return oldTab;
}
// 不超过扩容最大值,正常扩容到原来的两倍
else if (newCap < MAXIMUM_CAPACITY && oldCap >= DEFAULT_INITIAL_CAPACITY) {
// 扩容到原来两倍
newThr = oldThr << 1;
}
}
// 初始化时已有阈值, 将阈值赋给newCap, 再扩容.
// 例如:Map map = new HashMap<>(20);
else if (oldThr > 0) {
newCap = oldThr;
}
// 初始化数组
else {
// 初始化数组长度
newCap = DEFAULT_INITIAL_CAPACITY;
// 初始化数组容量阈值
newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
}
// 计算扩容之后新阈值
if (newThr == 0) {
// 计算新容量阈值
float ft = (float)newCap * DEFAULT_LOAD_FACTOR;
newThr = ((newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY) ? (int)ft : Integer.MAX_VALUE);
}
// 把新容量阈值赋值给公共属性threshold
threshold = newThr;
// 定义一个新数组把原数组的数据搬过来
@SuppressWarnings({"rawtypes","unchecked"})
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = newTab;
// 遍历老数组
if (oldTab != null) {
for (int j = 0; j < oldCap; ++j) {
Node<K,V> e = oldTab[j];
if (e != null) {
oldTab[j] = null;
// 空节点
if (e.next == null) {
newTab[e.hash & (newCap - 1)] = e;
}
// 树节点
else if (e instanceof TreeNode) {
// 拆分过程
// ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
}
// 链表节点
else {
// 低位头尾节点
Node<K,V> loHead = null;
Node<K,V> loTail = null;
// 高位头尾节点
Node<K,V> hiHead = null;
Node<K,V> hiTail = null;
Node<K,V> next;
// 搬运节点
do {
next = e.next;
// 寻桶寻址,扩容2倍,内存地址左移一位,判断新增加的高位是0还是1
// 是0 节点位置保持不变,是1,原数组长度 + 原节点位置
// 详情参考 图1-0
if ((e.hash & oldCap) == 0) {
if (loTail == null) {
loHead = e;
}
else {
loTail.next = e;
}
loTail = e;
}
else {
if (hiTail == null) {
hiHead = e;
}
else {
hiTail.next = e;
}
hiTail = e;
}
} while ((e = next) != null);
if (loTail != null) {
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
}
}
}
}
return newTab;
}
/**
* 可以有效减少hash冲突的可能性:高位低位参与异或运算
*/
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
/**
* 树形转换.
*/
final void treeifyBin(Node<K,V>[] tab, int hash) {
// 省略...
}
/**
* 红黑树
*/
static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
TreeNode<K,V> parent; // red-black tree links
TreeNode<K,V> left;
TreeNode<K,V> right;
TreeNode<K,V> prev; // needed to unlink next upon deletion
boolean red;
TreeNode(int hash, K key, V val, Node<K,V> next) {
super(hash, key, val, next);
}
// 省略...
}
}
08-12
1794

08-28
212

01-07
888
