Hashmap是基于哈希表的Mao接口的非同步实现,此实现提供所有可选的映射操作,幷允许使用null
hashmap实际上是一个 链表散列 的数据结构,数组和链表的结合体,数组中保存两种数据结构,一种是链表,一种是红黑树,当新建一个hashmap的时候就会初始化一个数组。
数组的散列性越大,碰撞概率就越低,数组的大小一定要是2的n次幂,如果数组该位置已经放置了元素,那么在该位置上的元素将以链表的形式存放,新加入的放在链表头,最先加入的放在链尾,如果没有元素在该位置上,就直接将该元素放到此数组中的该位置上
存储:当程序试图将将一个key-vlaue对放入HashMap中时,程序首先根据该key的hashcode()返回值决定Entry()的存储位置,如果两个entry的key的hashcode返回值相同,那他们的存储位置相同。
读取:从hashmap中get元素时,首先计算key的hashcode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到所需元素
hashmap中的key-value都是存在Entry中的,hashmap实现不同步,线程不安全
put()方法
public int hash(V key){
int h;
return (h = key.hashCode())^(h>>>16);//调用String的hashCode()得到hashcode值
}
public void put(V key,K value){//添加键对值
//通过key得到索引位置
int hash = hash(key);
int index = (table.length-1)&hash;
//判断该index位置是否存在节点
Node<K,V> firstNode= table[index];
//不存在,new Node直接放在该位置
if(firstNode == null){
table[index] = new Node(hash,key,value);
size++;
}else{
//遍历链表
Node<K,V> tmpNode = firstNode;
while(tmpNode.next!=null && !tmpNode.key.equals(key)){
tmpNode = tmpNode.next;
}
if(tmpNode.next == null){
if(tmpNode.key.equals(key)){
tmpNode.value = value;
}else{
tmpNode.next = new Node(hash,key,value);
size++;
}
}
}
}
get()方法
public K get(V key){//获取对应键对值
//通过key得到索引位置
int hash = hash(key);
int index = (table.length-1)&hash;
Node<K,V> firstNode = table[index];
if(firstNode == null){
return null;
}
if(hash == firstNode.hash && key == firstNode.key){
return firstNode.value;
}else{
//遍历链表
Node<K,V> tmpNode = firstNode.next;
while(tmpNode != null){
if(tmpNode.hash == hash && tmpNode.key == key){//当匹配到hash值相同,key相同的元素,返回value
return tmpNode.value;
}
tmpNode = tmpNode.next;
}
}
return null;
}
remove()方法
public boolean remove(V key){//删除key所对应的的键对值
int hash = hash(key);
int index = (table.length-1)&hash;
Node<K,V> firstNode = table[index];
if(firstNode == null){
return false;
}
if(hash == firstNode.hash && key == firstNode.key){
firstNode.value = null;
return true;
}else{
Node<K,V>tmpNode = firstNode.next;
while(tmpNode != null){
if(tmpNode.hash == hash && tmpNode.key == key){
tmpNode.value = null;
}
tmpNode = tmpNode.next;
}
}
return true;
}