创建MyHashMap
题目来源:(https://how2j.cn/k/collection/collection-hashcode/371.html)
HashMap原理
-----hashcode概念-----
所有的对象,都有一个对应的hashcode(散列值)
-----保存数据-----
准备一个数组,其长度是2000,并且设定特殊的hashcode算法,使得所有字符串对应的hashcode,都会落在0-1999之间
要存放名字是"gareen"的英雄,就把该英雄和名称组成一个键值对,存放在数组的1001这个位置上
要存放名字是"temoo"的英雄,就把该英雄存放在数组的1004这个位置上
要存放名字是"db"的英雄,就把该英雄存放在数组的1008这个位置上
要存放名字是"annie"的英雄,然而 "annie"的hashcode 1008对应的位置已经有db英雄了,那么就在这里创建一个链表,接在db英雄后面存放annie
-----查找数据-----
比如要查找gareen,首先计算"gareen"的hashcode是1001,根据1001这个下标,到数组中进行定位,(根据数组下标进行定位,是非常快速的) 发现1001这个位置就只有一个英雄,那么该英雄就是gareen.
比如要查找annie,首先计算"annie"的hashcode是1008,根据1008这个下标,到数组中进行定位,发现1008这个位置有两个英雄,那么就对两个英雄的名字进行逐一比较(equals),因为此时需要比较的量就已经少很多了,很快也就可以找出目标英雄
这就是使用hashmap进行查询,非常快原理。
这是一种用空间换时间的思维方式
代码如下
接口:
/**
* @author Small_Tsky
* @date 2020/3/11 - 9:13
**/
public interface IHashMap {
public void put(Object key,Object value);
public Object get(Object key);
}
hashcode:
public class hashCode {
public static int hsahcode(String s){
int hashcode =0;
if (s==null){
}else{
/*hashcode=(s[0]+s[1]+s[2]+...+s[n-1]+s[n])*23*/
char [] c = s.toCharArray();
for (int i = 0; i <c.length ; i++) {
hashcode +=c[i]*23;
}
if (hashcode>1999){
/*hashcode>1999取余数*/
hashcode = hashcode%2000;
}
}
return hashcode;
}
}
MyHashMap:
public class MyHashMap implements IHashMap {
private LinkedList<Entry> linked;/*链表*/
private Entry entry;/*键值对*/
private Object [] obj;/*对象数组*/
public MyHashMap(){
obj = new Object[2000];
}
@Override
public void put(Object key, Object value) {
int hashcode = hashCode.hsahcode(String.valueOf(key));
/*如果hashcode不重复的话,将键值对加到链表linkedzhong;
若存在,则需判断value是否一样,value一样:覆盖,value不一样:
则把新的键值对加入到linked链表的后面*/
if (obj[hashcode]==null){
linked =new LinkedList<>();
entry = new Entry(key,value);
linked.add(entry);
obj[hashcode] = linked;/*将linked记录到obj数组里,在get方法中遍历用*/
}else {
/*key相同覆盖上一个value*/
boolean judge = false;
for (Entry entry:linked) {
if (entry.key.equals(key)){
entry.value = value;/*覆盖*/
judge =true;
}
}
if (!judge){
linked = new LinkedList<>();/*创建新的链表*/
linked.add(entry);/*在lined后面插入新的entry*/
}
}
}
@Override
public Object get(Object key) {
Object value = null;
int hashcode = hashCode.hsahcode(key.toString());
/*判断key对应的数组存不存在*/
if (obj[hashcode] !=null){
/*将数组obj转化成linkedlist,迅速找出对应key的linked*/
linked = (LinkedList<Entry>) obj[hashcode];
for (Entry entry:linked) {
if (entry.key.equals(key)){
value=entry.value;
}
}
}
return value;
}
}
关键在于数组上每一个位置(hashcode)都可以创建一个或多个链表,让数组记录所有的链表,从而方便遍历