首先必须明确HashMap的数据结构,网上有很多解释;手动实现HashMap最主要就是表现出来数组加链表的结构,以及可用的put和get方法,体现出hash碰撞时候的数据处理即可。
//定义接口
public interface MyMap<K, V> {
//长度(这里指的是数组的长度)
int size();
//是否为空
boolean isEmpty();
//get方法
Object get(Object key);
//put方法
Object put(Object key, Object value);
//内部接口 模仿Map.Entry
interface Entry {
Object getKey();
Object getValue();
}
}
//实现类
public class MyMapImpl<K, V> implements MyMap {
// 默认容量
private final int DEFAULT_CAPACITY = 16;
// 数组存放Node容器
Node[] table = new Node[DEFAULT_CAPACITY];
// 长度
private int size = 0;
// 静态内部类
static class Node implements Entry {
// 属性
int hash;
Object key;
Object value;
Node next;
// 构造器
public Node(int hash, Object key, Object value, Node next) {
super();
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
@Override
public Object getKey() {
return key;
}
@Override
public Object getValue() {
return value;
}
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public Object get(Object key) {
int hash = hashcode(key);
int indexOf = indexOf(hash, table.length);
Node node = table[indexOf];
while (node != null) {
if (node.key.equals(key) && node.hash == hash) {
return node.value;
}
node = node.next;
}
return null;
}
public int hashcode(Object key) {
return key.hashCode();
}
//这里给出的索引计算是为了测试碰撞比如 key="1"和key="a"会出现hash碰撞
public int indexOf(int hash, int length) {
return hash % length;
}
@Override
public Object put(Object key, Object value) {
// 先判断数组中有没有这个值
int hashcode = hashcode(key);
int indexOf = indexOf(hashcode, table.length);
Node node = table[indexOf];
if (node == null) {
// 则说明不存在,即往数组里面添加数据
table[indexOf] = new Node(hashcode, key, value, null);
++size;
} else {
// 在链表里面添加 已经发生碰撞了
//第一个判断是看是否在数组中有相同的key和hash
if (node.hash == hashcode && node.key == key || node.key.equals(key)) {
// 此时应该新值替换旧值
Object oldValue = node.value;
node.value = value;
return oldValue;
} else {
// 否则循环链表
while (true) {
if (node.next == null) {
node.next = new Node(hashcode, key, value, null);
break;
}
if (node.next.hash == hashcode && node.next.key == key || node.next.key.equals(key)) {
break;
}
node = node.next;
}
}
}
//扩容
if (size == table.length) {
Node[] tableNew = new Node[table.length * 2];
System.arraycopy(table, 0, tableNew, 0, table.length);
table = tableNew;
}
return null;
}
}
//测试类
public class MyMapTest {
public static void main(String[] args) {
MyMap<String,Object> map = new MyMapImpl<>();
//map.put("name", "薛东");
//map.put("age", 28);
map.put("1", 111);
map.put("a", 222);
//System.out.println(map.get("name"));
//System.out.println(map.get("age"));
System.out.println(map.size());
System.out.println(map.get("1"));
System.out.println(map.get("a"));
}
}