面试题:如何设计实现一个HashMap?

本文解析了Java中的MyHashMap类,介绍了散列函数的使用、冲突解决策略(链地址法)、以及如何在负载因子达到阈值时进行扩容,详细展示了整体设计和关键方法的实现过程。
摘要由CSDN通过智能技术生成

整体的设计

散列函数:hash方法+hash&(table.length-1)

冲突解决:链地址法

扩容:节点重新hash获取位置

整体设计思维导图

整体代码

import java.security.Key;

public class MyHashMap<K,V> {
  class Node<K,V>{
        private K key;
        private V value;
        private Node<K,V> next;

        public Node(K key, V value) {
            this.key = key;
            this.value = value;
        }

        public Node(K key, V value, Node<K, V> next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }
    //默认容量
    //默认容量
    final int DEFAULT_CAPACITY = 16;
    //负载因子
    final float LOAD_FACTOR = 0.75f;
    //HashMap的大小
    private int size;
    //数组
    Node<K,V>[] table;

    public MyHashMap() {
        table=new Node[DEFAULT_CAPACITY];
        size=0;
    }
    public MyHashMap(int capacity){
        table=new Node[capacity];
        size=0;
    }
    public int getindex(K key,int length){
        int h;
        //hash方法:获取key对应的hash值
        h=((key == null) ? 0 : key.hashCode()^(key.hashCode()>>>16));
        //hash&(table.length)获取位置索引
        int index=h&(length-1);
        return index;
    }
    public void put(K key,V value){
        //判断是否需要进行扩容:如果需要扩容resize,执行putVal方法
        if(size>=table.length*LOAD_FACTOR) resize();
        putVal(key,value,table);

    }
    public void putVal(K key,V value,Node<K,V>[] table){
        //获取元素插入位置
        int index=getindex(key,table.length);
        //当前位置为空,直接插入
        Node node=table[index];
        if(node==null){
            table[index]=new Node<>(key,value);
            size++;
            return;
        }
        //位置不为空,发生冲突,遍历链表
        while (node!=null){
            //如果元素key和节点相同,覆盖
            if(node.key.hashCode()==key.hashCode()&&(node.key==key||node.key.equals(key))){
                node.value=value;
                return;
            }
            // 否则新建节点插入链表尾部
            if(node.next==null){
                node.next=new Node(key,value,table[index]);
            }
            node=node.next;
        }
        size++;
    }
    public void resize(){
//        创建两倍容量的新数组
        Node<K,V>[] newtable=new Node[table.length*2];
//        将当前桶数组的元素重新散列到新的数组
        size=0;//size大小重新计算
        for (int i=0;i<table.length;i++){
            //为空跳过
            if (table[i]==null){
                continue;
            }
            Node<K,V> node=table[i];
            while (node!=null){
                putVal(node.key,node.value,newtable);
                node=node.next;
            }
        }
//        新数组置为map的桶数组
        table=newtable;
    }
    public V get(K key){
        //获取key对应的索引
        int index=getindex(key,table.length);
        if(table[index]==null)return null;
        Node<K,V> node=table[index];
        //查找链表
        while (node!=null){
            if(node.key.hashCode()==key.hashCode()&&(node.key==key||node.key.equals(key))){
                return node.value;
            }
            node=node.next;
        }
        return null;
    }
    public int size(){
        return size;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值