java collection之 HashMap

来源:互联网 发布:java string split . 编辑:程序博客网 时间:2024/06/12 00:32

HashMap是collection中一个常用的类,提供常见的Key-Value的键值对访问方法

最长用的莫过于put get remove 等增删改查功能

详细信息网上大把,简单看下它的内部算法

总体来说,HashMap遇到冲突时用的是拉链式解决方法,内部存储一个Entry []table来存储实际的数据,table中的每个元素保存一个Entry 。如果两个元素有相同的hash值,那么计算出来的地址也一样,此时,这两个元素存储在table数组中的同一个位置,假设两个元素a1,a2,a1.hash = a2.hash.则计算出来的index必然一样。

假设a1先插入则,table[indexOfa1] = a1并且,a1.next =a2,由此可以看出,如果index值一样的元素,新进来的放在链头,先增加进来的放在链尾。下面详细分析

  1. put(Object key, Object value): 增加一个键值

             刚开始Object k = maskNull(key); //如果传人的key是null,就用内部的一个Object作为key,这也是HashMap支持null键的原因

            接着, int hash = hash(k);//根据元素的hashCode计算内部hash,查了些资料,也不知道为什么如此转变hash,哪位大哥知道告诉我啊

          int i = indexFor(hash, table.length)//根据hash, 数组的长度计算出内部索引值,一般都用取模的方法,这里使用的是hash&table.length-1直接计算出来,速度肯定比取模快,哪位大哥知道这是什么考虑啊?

         接着通过for (Entry e = table[i]; e != null; e = e.next) {...}在计算出的索引i处查找是否有相同关键字的已经添加,如果有则替换当前key的值,返回旧值,否则创建一个新的Entry,并插入table[i],且新插入的作为table[i]处的链表头。  创建操作通过调用 addEntry(hash, k, value, i)实现,如果容量超出限制则重新分配空间,并将所有数据移植新的[]table

       2.   get  : get比较简单

             Object k = maskNull(key);//找出key,如果key为null,则返回默认key
            int hash = hash(k);//得到内部hash
            int i = indexFor(hash, table.length;//计算index    
           Entry e = table[i]//取出索引处的值

          剩下的比较简单,通过一个while循环不断比较链表中的Entry是否相同先比较hash,再比较Entry中的key和目标key,调用他们的equals方法。

     3、remove                    

        remove基本流程和get相同,直接看源码即可,注意的是删除后要讲删除结点前后元素连接起来

    4、modCount的功能

      以前总是奇怪,HashMap怎么能自己检测并发问题,原来就是这个modCount在捣鬼,每次增加或者删除一个元素就modCount++,如果同时有两个线程删除HashMap则modCount不一样,抛出ConcurrentModificationException()^_^

剩下的各种Iterator只是应用透明的迭代访问模式提供对HashMap的不同访问接口

其他操作都是在增删改查基础上的,看源代码就可以了

就是hash, indexFor两个方法没看明白为什么这么干

谁知道告诉我啊! 总体写的乱七八糟以后再整理吧

原创粉丝点击