整体的设计:
散列函数:hash方法+hash&(table.length-1)
冲突解决:链地址法
扩容:节点重新hash获取位置
整体设计思维导图
整体代码
import java.security.Key;
public class MyHashMap<K,V> {
class Node<K,V>{
private K key;
private V value;
private Node<K,V> next;
public Node(K key, V value) {
this.key = key;
this.value = value;
}
public Node(K key, V value, Node<K, V> next) {
this.key = key;
this.value = value;
this.next = next;
}
}
//默认容量
//默认容量
final int DEFAULT_CAPACITY = 16;
//负载因子
final float LOAD_FACTOR = 0.75f;
//HashMap的大小
private int size;
//数组
Node<K,V>[] table;
public MyHashMap() {
table=new Node[DEFAULT_CAPACITY];
size=0;
}
public MyHashMap(int capacity){
table=new Node[capacity];
size=0;
}
public int getindex(K key,int length){
int h;
//hash方法:获取key对应的hash值
h=((key == null) ? 0 : key.hashCode()^(key.hashCode()>>>16));
//hash&(table.length)获取位置索引
int index=h&(length-1);
return index;
}
public void put(K key,V value){
//判断是否需要进行扩容:如果需要扩容resize,执行putVal方法
if(size>=table.length*LOAD_FACTOR) resize();
putVal(key,value,table);
}
public void putVal(K key,V value,Node<K,V>[] table){
//获取元素插入位置
int index=getindex(key,table.length);
//当前位置为空,直接插入
Node node=table[index];
if(node==null){
table[index]=new Node<>(key,value);
size++;
return;
}
//位置不为空,发生冲突,遍历链表
while (node!=null){
//如果元素key和节点相同,覆盖
if(node.key.hashCode()==key.hashCode()&&(node.key==key||node.key.equals(key))){
node.value=value;
return;
}
// 否则新建节点插入链表尾部
if(node.next==null){
node.next=new Node(key,value,table[index]);
}
node=node.next;
}
size++;
}
public void resize(){
// 创建两倍容量的新数组
Node<K,V>[] newtable=new Node[table.length*2];
// 将当前桶数组的元素重新散列到新的数组
size=0;//size大小重新计算
for (int i=0;i<table.length;i++){
//为空跳过
if (table[i]==null){
continue;
}
Node<K,V> node=table[i];
while (node!=null){
putVal(node.key,node.value,newtable);
node=node.next;
}
}
// 新数组置为map的桶数组
table=newtable;
}
public V get(K key){
//获取key对应的索引
int index=getindex(key,table.length);
if(table[index]==null)return null;
Node<K,V> node=table[index];
//查找链表
while (node!=null){
if(node.key.hashCode()==key.hashCode()&&(node.key==key||node.key.equals(key))){
return node.value;
}
node=node.next;
}
return null;
}
public int size(){
return size;
}
}