简单实现一个HashMap(get方法/put方法)
HashMap采用哈希算法实现,是Map接口最常用的实现类。 由于底层采用了哈希表存储数据,我们要求键不能重复,如果发生重复,新的键值对会替换旧的键值对。 HashMap在查找、删除、修改方面都有非常高的效率。
下面是我简易实现HashMap的代码:
Node.java
//定义节点类
public class Node<K,V>{
int hash; //哈希值
K key;
V value;
Node next;//下一个节点
}
MyHashMap.java
public class MyHashMap<K,V> {
Node[] table;//位桶数组
int size;//存放键值对的个数
public MyHashMap() {
table=new Node[16];
}
//实现put 方法:存入键值对,并解决了键重复的时候覆盖相应的节点。
public void put(K key,V value) {
//如果要完善,还要考虑数组扩容问题
//定义新的节点对象
Node newNode=new Node();//建立新的节点
newNode.hash=MyHash(key.hashCode(), table.length);
newNode.key=key;
newNode.value=value;
newNode.next=null;
Node temp=table[newNode.hash];
Node iterLast=null; //正在遍历的最后一个元素
boolean keyRepeat=false;//重复判断标记
if(temp==null) {
//此处数组的元素为空,就直接将节点放进去
table[newNode.hash]=newNode;
size++;
}else {
//此处数组不为空,则遍历对应链表
while(temp!=null) {
//判断key值,如果重复,则进行覆盖
if(temp.key.equals(key)) {
keyRepeat=true;//键值重复
temp.value=value;//只需要覆盖value即可,其它的不用改变
break;
}else {
//key不重复
iterLast=temp;//保存最后的节点
temp=temp.next;//遍历下一个节点
}
}
if(!keyRepeat) {
iterLast.next=newNode;
size++;
}
}
}
//创建自己的Hash方法:将hashCode按照某种方法运算得到一个hash值,由这个值计算在位桶数组的位置。
public int MyHash(int v,int length) {
System.out.println("hash in my hash:"+(v&(length-1)));//直接位运算,效率高
System.out.println("hash in my hash:"+(v%(length-1)));//取模运算,效率低
return v&(length-1);
}
//增加get方法:根据键对象获得相应的值对象
public V get(K key) {
int hash=MyHash(key.hashCode(), table.length);//获取哈希值
V value=null;
if(table[hash]!=null) {
Node temp=table[hash];
while(temp!=null) {
if(temp.key.equals(key)) {//如果相等,则说明找到了对应的键值,则返回value值
value=(V)temp.value;
break;
}else {//如果没找到,则遍历下一个节点
temp=temp.next;
}
}
}
return value;
}
//重写toString方法,方便查看MAP中键值对的信息。
@Override
public String toString() {
StringBuilder sb=new StringBuilder("{");
for(int i=0;i<table.length;i++) {//遍历位桶数组
Node temp=table[i];
while(temp!=null) {//遍历链表
sb.append(temp.key+":"+temp.value+",");
temp=temp.next;
}
}
sb.setCharAt(sb.length()-1, '}');
return sb.toString();
}
public static void main(String[] args) {
MyHashMap<Integer,String> m=new MyHashMap<>();
m.put(10, "aa");
m.put(20, "bb");
m.put(30, "cc");
m.put(30, "a");
System.out.println(m);
System.out.println(m.get(30));
}
}