实现简单的HashMap
程序员文章站
2022-03-29 16:06:10
...
HashMap概述
HashMap底层实现是采用了哈希表,属于一种基本的数据结构,而哈希表的基本结构是“数组+链表”之前我们说到数组和链表,它们之间的优缺点如下
- 数组的查询速度快,增删效率低
- 链表的增删效率高,查询速度低
这里我们想如何才能把这两者的优势集中起来呢?于是哈希表就出来了。
我们手写一个HashMap类来看一下存储原理
package com.boker.Collection;
/**
* 用于MyHashMap中
*/
public class Node2 <K,V>{
int hash;
K key;
V value;
Node2 next;
}
package com.boker.Collection;
/**
* 哈希表底层是数组+链表
* @author Administrator
*
*/
public class MyHashMap<K,V> {
Node2[] table; //数组
int size; //存放键值对的个数
//构造方法
public MyHashMap() {
table = new Node2[16]; //长度一般为2的整数幂
}
//存放数据
public void put(K key , V value) {
//新建一个节点对象
Node2 newNode = new Node2();
//新节点的哈希值
newNode.hash = myHash(key.hashCode(),table.length);
newNode.key = key;
newNode.value = value;
newNode.next = null;
//当前数组
Node2 temp = table[newNode.hash];
//正在遍历的最后一个元素
Node2 iterLast = null;
//key是否重复
boolean keyIsRepeat = false;
if(temp == null) {
//此处数组为空,直接将新节点放进去
table[newNode.hash] = newNode;
size++;
}else {
//此处数组不为空,遍历对应的链表
while(temp != null) {
if(temp.key.equals(key)) {
//判断key如果重复,则覆盖(只需要覆盖value)
keyIsRepeat = true;
temp.value = value;
break;
}else {
//不重复,则遍历下一个
iterLast = temp;
temp = temp.next;
}
}
//key没有重复的话,则添加到当前数组链表的最后
if(!keyIsRepeat) {
iterLast.next = newNode;
size++;
}
}
}
//获取值
public V get(K key) {
int hash = myHash(key.hashCode(),table.length);
V value = null;
//对应的元素位置不为空
if(table[hash] != null) {
Node2 temp = table[hash];
while(temp != null) {
//如果相等,则说明找到了键值对,返回对应的value,否则继续找
if(temp.key.equals(key)) {
value = (V)temp.value;
break;
}else {
temp = temp.next;
}
}
}
return value;
}
public int myHash(int v , int length) {
// //位运算,效率高
// System.out.println("hash in myHash"+(v&(length-1)));
// //取模运算,效率低
// System.out.println("hash in myHash"+(v%(length-1)));
return v&(length-1);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{") ;
//遍历数组
for(int i=0; i<table.length; i++) {
Node2 temp = table[i];
//遍历链表
while(temp != null) {
sb.append(temp.key+"="+temp.value+",");
temp = temp.next;
}
}
sb.setCharAt(sb.length()-1, '}');
return sb.toString();
}
}
package com.boker.Collection;
public class TestMap {
public static void main(String[] args) {
MyHashMap<Integer,String> m = new MyHashMap<>();
m.put(1, "12");
m.put(2, "22");
m.put(3, "32");
m.put(1, "2");
System.out.println(m);
System.out.println("m容器的第一个键值为:"+m.get(1));
}
}
运行结果: