public class MyHashMap {
public Node[] HeadNode = new Node[11];
public int size = 0;
public float loadFactor = 0.75f;// 加载因子
public class Node {
Node next;// 指向下一个节点
Object key;
Object value;
// 构造方法
public Node(Object key, Object value) {
this.key = key;
this.value = value;
}
}
// 向哈希表中添加键值对
public void put(Object key, Object value) {
// 判断是否扩容
if (size * 1.0 / HeadNode.length > loadFactor)
rehash();
//计算初始位置
int index = hash(key, HeadNode.length);
Node node = new Node(key, value);
//调用真正的插入方法
input(node, HeadNode, index);
}
// 添加函数
private void input(Node node, Node[] HeadNode, int index) {
// 如果HeadNode为空,则把当前节点赋给头节点
if (HeadNode[index] == null) {
HeadNode[index] = node;
} else {
// 否则,遍历链表
Node temp = HeadNode[index];
if (node.key == temp.key) {
System.out.println("键值" + temp.key + "已存在");
} else {
while (temp.next != null) {
temp = temp.next;
}
}
// 把要加入的节点加到链表最后
temp.next = node;
}
}
// hash过程是获取hashcode,其实我的理解是:就是找它该在哪一个链表中
public int hash(Object key, int length) {
int index = -1;
if (key != null) {
// key是Object类型的,要转成int类型的才能进行取余运算。
// 先转成字符数组
char[] c = key.toString().toCharArray();
int tokey = 0;
// 计算转换的key值
for (int i = 0; i < c.length; i++) {
tokey += c[i];
}
index = tokey % length;
}
return index;
}
public void rehash() {
// 每次扩展都把当前的哈希表增大一倍
Node[] newHeadNode = new Node[HeadNode.length * 2];
// 把原来的哈希表依次重新hash进去
for (int i = 0; i < HeadNode.length; i++) {
if (HeadNode[i] != null) {
//寻找新的位置
int newindex = hash(HeadNode[i].key, HeadNode.length * 2);
// 重新new新的节点来保存原理hash表中的键值对
Node rehashheadnode = new Node(HeadNode[i].key, HeadNode[i].value);
//插入进去
input(rehashheadnode, newHeadNode, newindex);
//重复 处理链上的元素
Node temp = HeadNode[i];
while (temp.next != null) {
temp = temp.next;
Node rehashnextnode = new Node(temp.key, temp.value);
int nextindex = hash(temp.key, newHeadNode.length);
input(rehashnextnode, newHeadNode, nextindex);
}
}
}
// 重新设置节点数组的引用,就是把newHeadNode数组的地址赋给HeadNode(可以理解为让HeadNode指向newHeadNode)
HeadNode = newHeadNode;
}
// 获取键值对应的value
public Object getValue(Object key) {
int index = hash(key, HeadNode.length);
// 先找到在哪条链中
Node temp = HeadNode[index];
// 先判断头节点是否为空
if (temp == null)
return null;
else {
if (key == temp.key)
return temp.value;
else {// 遍历链表
while (temp.next != null) {
temp = temp.next;
if (key == temp.key)
return temp.value;
}
}
}
return null;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
}