手工实现HashMap(简单版)- get put remove size方法

手工实现HashMap ,包括get()   put()   remove()   size()方法,当然,这是线程不安全的,不过可以学习。

本文代码是在https://blog.csdn.net/weixin_43003240/article/details/87534836 这篇文章上进行改进的,其博客的71行

iterLast = newNode;  这个是有问题的,要对链表进行插入才行,此作者直接进行赋值,如果你用很多个元素进行测试,可以看到,此作者运行出的结果最大只有16个,就是因为没有对链表进行插入。因此,本文对其进行改进如下(也就是三行代码的事情):

//采用头插法进行插入元素
Node2 first = table[newNode.hash];
newNode.next = first;
table[newNode.hash] = newNode;
package com.itisyue.base.map;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

class Node2 {
    int hash;
    Object key;
    Object value;
    Node2 next;
}

public class MyHashMap {
    private Node2[] table;//位桶数组。bucket array
    private Long size=0L;//存放的键值对的个数

    public MyHashMap() {
        table = new Node2[16];//长度一般定义成2的整数幂
    }

    public Object get(Object key) {
        int hash = myHash(key.hashCode(), table.length);
        Object value = null;

        if (table[hash] != null) {
            Node2 temp = table[hash];

            while (temp != null) {
                if (temp.key.equals(key)) {//如果相等,则说明找到了键值对,返回相应的value
                    value = temp.value;
                    break;
                } else {
                    temp = temp.next;
                }
            }
        }
        return value;
    }

    public void put(Object key, Object 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;//正在遍历的最后一个元素

        boolean keyRepeat = false;

        if (temp == null) {
            //此处数组元素为空,则直接将新节点放进去
            table[newNode.hash] = newNode;
            size++;
        } else {
            //此处数组元素不为空。则遍历对应链表。。
            while (temp != null) {
                //判断key如果重复,则覆盖
                if (temp.key.equals(key)) {
                    keyRepeat = true;
                    System.out.println("key重复了!");
                    temp.value = value;//只是覆盖value即可。其他的值(hash,key,next)保持不变。
                    break;
                } else {
                    //key不重复,则遍历下一个
                    iterLast = temp;
                    temp = temp.next;
                }
            }
            if (!keyRepeat) {
            	//采用头插法进行插入元素
				Node2 first = table[newNode.hash];
				newNode.next = first;
				table[newNode.hash] = newNode;

                //iterLast = newNode;
                size++;
            }
        }
    }


	public Object remove(Object key) {
		//定义新的节点对象
		Node2 newNode = new Node2();
		newNode.hash = myHash(key.hashCode(), table.length);
		newNode.key = key;
		newNode.value = "";
		newNode.next = null;

		Node2 temp = table[newNode.hash];

		Node2 preNode = null;//key匹配的前一个节点

		boolean keyRepeat = false;

		if (temp == null) {
			return null;
		} else {
			preNode = temp;
			Long current = 0L;
			//此处数组元素不为空。则遍历对应链表。。
			while (temp != null) {
				//判断key相等
				if (temp.key.equals(key)) {
					if(current==0L){
						//说明是第一个元素
						table[newNode.hash].next = temp.next;
					}else{
						preNode.next = temp.next;//删除当前节点
					}
					size--;
					return temp.value;
				} else {
					//key不相等,则遍历下一个
					preNode = temp;
					temp = temp.next;
					current++;
				}
			}
		}
		return null;
	}

    public Long size(){
		return size;
	}

    public static int myHash(int v, int length) {
        System.out.println(v+" hash in myHash:" + (v & (length - 1)));
        //System.out.println(v+" hahs in myHash:" + (v % (length - 1)));
        return v & (length - 1);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("{");
        //遍历bucket数组
        for (int i = 0; i < table.length; i++) {
            Node2 temp = table[i];
			StringBuilder sb1 = new StringBuilder("{");
            //遍历链表
            while (temp != null) {
                sb.append(temp.key + ":" + temp.value + ", ");
				sb1.append(temp.key + ":" + temp.value + ", ");
                temp = temp.next;
            }
            if(sb1.length()>1){
				sb1.setCharAt(sb1.length() - 2, '}');
			}else{
            	sb1.append(" }");
			}
			System.out.println("table["+i+"] node is : " + sb1.toString());
        }
        sb.setCharAt(sb.length() - 1, '}');
        return sb.toString();
    }

    public static void main(String[] args) {
        MyHashMap m = new MyHashMap();

		Map<Object,Object> hashMap = new HashMap<>();

        for(int i=0;i<160;i++){
        	m.put(i,"data" + i);
			//hashMap.put(i,"data" + i);
		}
        Object deleteKey = -1;
		System.out.println("删除元素 key="+deleteKey+", value="+m.remove(deleteKey));
        System.out.println(m);

        System.out.println("元素个数:" + m.size());


//        hashMap.remove(0);
//		Iterator it = hashMap.entrySet().iterator();
//		while (it.hasNext()) {
//			Map.Entry entry = (Map.Entry) it.next();
//			int code = entry.hashCode();
//			Object key = entry.getKey();
//			Object value = entry.getValue();
//			System.out.println("code:"+code+"---key:" + key + "---" + "value:" + value);
//		}
//		System.out.println(hashMap);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值