public interface MyMap<K, V> {
public V put(K key, V value);
public V get(K key);
public int size();
interface Entry<K, V> {
//修改kv的值
V setValue(V value);
//修改元素的next结点
Entry<K, V> setNext(Entry<K, V> next);
}
public class MyHashMap<K, V> implements MyMap<K, V> {
//定义一个用于存放Entry对象的数组
Node<K, V>[] table = null;
//HashMap数组的默认长度
private static int defaultCapacity = 16;
//默认的加载因子,扩容
private static float defaultLoadFactory = 0.75f;
//数组大小
transient int size;
@Override
public V put(K key, V value) {
if (table == null) {
table = new Node[this.defaultCapacity];
}
//1、通过hash算法,判断插入的位置
int index = getIndex(key,this.defaultCapacity);
//2、判断是不是修改数据
Node<K, V> node = table[index];//node节点
while (node != null) {
if (node.key.equals(key)) {//第一个node节点的key相等
node.setValue(value);//覆盖
} else {//不相等,再判断下一个节点的key
node = node.next;
}
}
if (size >= this.defaultCapacity * this.defaultLoadFactory) {
//扩容
resize();
}
//2、创建Node对象,并且保存到数组中
table[index] = new Node<>(key, value, table[index]);
this.size++;
return value;
}
private void resize() {
Node<K, V>[] newTable = new Node[this.defaultCapacity << 1];//左移1位,2的n次方
Node<K, V> node = null;
for (int i = 0; i < table.length; i++) {//遍历扩容之前的数组
node = table[i];
while (node != null) {//有元素
//取到老元素的下一个元素,先拿出来放着
Node<K,V> temp = node.next;
//拿到key,重新计算key在新数组中的下标
int index = getIndex(node.key,newTable.length);
//把老元素指向链表中下一个元素的指针指向新数组里的i下标的链表中的第一位
node.setNext(newTable[i]);
//把老元素拿到新数组里
newTable[i] = node;
//然后再按照相同的方式,计算老元素的下一个元素(链表中的数据)
node = temp;
}
}
}
private int getIndex(K key,int length) {
if (key == null) {
return 0;
}
int index = key.hashCode() & (length - 1);
return index;
}
@Override
public V get(K key) {
if (table == null) {
return null;
}
int index = getIndex(key,this.defaultCapacity );
Node<K, V> node = table[index];
while (node != null) {
if (node.key.equals(key)) {
return node.value;
} else {
node = node.next;
}
}
return null;
}
@Override
public int size() {
return 0;
}
static class Node<K, V> implements Entry<K, V> {
K key;
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 V setValue(V value) {
V old = this.value;
this.value = value;
return old;
}
@Override
public Entry<K, V> setNext(Entry<K, V> next) {
Entry<K, V> old = this.next;
this.next = (Node<K, V>) next;
return old;
}
}