HashMap底层分析以及手写实现

HashMap平时我们都在用,底层效率挺高的

我对HashMap的理解就是使用了数组+链表的结构

当我们插入数据的时候,通过传入的key的hash来计算应该放的位置

    如果计算出来的索引有数据了,就遍历其下的链表

        如果链表中有key与传进来的一致,就改掉当前遍历到的节点的value

        如果遍历到最后也没有key一致的节点,就添加节点到最后

    如果计算出来的索引位置中没有数据直接放到哪个位置了


我们插入数据的时候还要进行扩容检测,新容器的容量是之前的两倍,

这是为了保证数组不会越界并且计算的索引不为0,因为我们的计算索引是通过与运算得出的


扫描二维码关注公众号,回复: 3136373 查看本文章

获得数据的话就是接收一个key,然后计算索引,如果计算出来的索引的key和传进来的一致,那就返回这个值

如果不一致,那就遍历其下的链表,如果有节点的key与传递进来的key一致,就返回这个节点的value


接下来就是代码



这是放数据的方法

注释写的很详细


public void put(K k,V v){

    //先检测大小是否足够
    //如果大小不够就扩容
    if(!checkSize()){
        capacity();
    }
    //先判断计算出来的索引位置是否有数据

    //如果没有数据直接填进去,然后返回
    if(bucket[indexFor(k)]==null){
        bucket[indexFor(k)]=new Node<>(k,v);
        size++;
        return;
    }

    //走到这里说明指定索引有数据,然后就往指定位置的链表中填入数据
    for(Node<K,V> node=bucket[indexFor(k)];node!=null;node=node.next){
        //如果链表中有节点的key和我们放进去的一致,那就直接替换掉值
        if(k.hashCode()==node.getKey().hashCode()&&k.equals(node.getKey())){
            node.setValue(v);
            return;
        }
        //走到这里说明链表没有key和传递过去的key一致,那就添加节点到末端
        if(node.next==null){
            //那就加入到节点中
            Node<K,V> newNode=new Node<>(k,v);
            newNode.setLast(node);
            node.setNext(newNode);
            return;
        }
    }
}

这是获得数据的代码



public V get(K k){
    System.out.println(Arrays.toString(bucket));
    //如果指定索引的对象的key与我们传递过来的一致,那这个就是我们想要的
    if(bucket[indexFor(k)]!=null&&bucket[indexFor(k)].getKey().hashCode()==k.hashCode()&&k.equals(bucket[indexFor(k)].getKey())){
        return bucket[indexFor(k)].getValue();
    }

    //走到这里了就说明数组中没有我们想要的,那我们就在指定索引下的链表中遍历查找
    for(Node<K,V> node=bucket[indexFor(k)];node!=null;node=node.next){
        if(k.hashCode()==node.getKey().hashCode()&&k.equals(node.getKey())){
            return node.getValue();
        }
    }
    return null;
}


完整代码我已经上传到GitHub 欢迎 Issue

我的GitHub


猜你喜欢

转载自blog.csdn.net/u011546032/article/details/80465261