今天看了一下自己的 简单实现HashMap,发现好多问题,今天又重新实现了一下,整体思想还是基于数组加链表的形式实现的。思路如下:数组下挂了一个个链表。
首先创建一个类作为链表。很简单 只是简单的记录了一下Key,Value,以及 下一个节点(学过C语言的同学,可以理解成指针),默认构造方法,以及传参构造方法。
/**
* 自定义链表
* @param <K,V>
*/
public class Node<K,V> {
//当前Key
private K key;
//当前Key
private V value;
//指针
private Node<K,V> next;
public Node(){
}
public Node(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public Node<K, V> getNext() {
return next;
}
public void setNext(Node<K, V> next) {
this.next = next;
}
}
然后在实现 hashMap的get和put方法。其中要注意的是java中的值传递和引用传递(https://blog.csdn.net/bntx2jsqfehy7/article/details/83508006),可以参考一下这个帖子。
/**
* 自定义 HashMap
* 主要通过 hashMap的可以计算Key Hash值
* 然后将 hash值进行取余,然后 将取余的值作为下标,将内容放在改 item下的链表中
*/
public class MyHashMap<K,V>{
Integer iniSize = 16;
Node<K,V>[] nodes = null;
public MyHashMap() {
this.nodes = new Node[iniSize];
}
public MyHashMap(Integer size) {
this.nodes = new Node[size];
this.iniSize = size;
}
public void put(K k,V v) throws Exception{
//判断Key是否已经存在
Integer i = getIndex(k);
//如果是该下标的第一个节点
if(null == nodes[i]){
nodes[i] = new Node<>(k,v);
}else{
Node node = findNode(nodes[i],k);
//如果Key存在
if(null!=node){
throw new Exception("key不能重复");
}else{
//key不存在,直接加在链表下面 (如果Hashcode值发生碰撞解决)
addNode(nodes[i],k,v);
}
}
}
public V get(K k){
Integer i = getIndex(k);
Node<K, V> indexNode = nodes[i];
Node node = findNode(indexNode, k);
return (V) node.getValue();
}
//计算下标
private Integer getIndex(K k){
String putKey = String.valueOf(k);
Integer index = putKey.hashCode()%iniSize;
return index;
}
//链表递归查询节点,根据首节点 key值
private Node findNode(Node node,K k){
if(node == null){
return null;
}
Object key = node.getKey();
if(!key.equals(k)){
return findNode(node.getNext(),k);
}else{
return node;
}
}
//链表递归查询最后的节点
private Node findLastNode(Node node){
//如果是该下标的第一个节点
if(null == node){
return null;
}
Node next = node.getNext();
if(null!=next){
findLastNode(next);
}else{
return node;
}
return null;
}
//链表增加节点,首个节点,Key,Value
private void addNode(Node node,K k,V v){
Node lastNode = findLastNode(node);
Node newNode = new Node(k,v);
lastNode.setNext(newNode);
}
}
最后测试Main方法
public static void main(String[] args) throws Exception {
System.out.println(String.format("Aa的HashCode是%s ","Aa".hashCode()));
System.out.println(String.format("BB的HashCode是%s ","BB".hashCode()));
//设置一样HashCode的值
MyHashMap<String,Integer> myHashMap = new MyHashMap<String, Integer>();
myHashMap.put("Aa",1);
myHashMap.put("BB",2);
//获取值
Object value = myHashMap.get("BB");
System.out.println(value);
}
打印的值如下:
Aa的HashCode是2112
BB的HashCode是2112
2