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