`
bmqnc
  • 浏览: 122712 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

HashMap源代码分析

    博客分类:
  • java
阅读更多
今天看了一下HashMap的源代码,除了数学Hash部分没看懂,其他基本都看懂了。

HashMap中其实主要使用一个数组来保存值的,一个对象在map中要想相等,有两个条件,第一个是它的哈希码必须相等,即在map的内部数组的桶索引必须相等,第二是它的key值也必须相等,因为map中是不允许存在key值相同的对象的。

唯一看到一个地方感觉不爽的是containsValue方法,因为这个方法是遍历整个数组来进行查找,不过本身map对value值就没有做出限制,因此这里也只能用这种方式进行查找。

还有一个比较有意思的地方时它对null key的处理,map中将所有null key放置在内部数组的index为0的位置上,当然,index为0的位置本身还可能放置其它对象。
因为null key比较特别,包括null value,所以内部有几个private方法是针对null key与null value的。

还有一个是注意它的clear函数的用法,里面清空的时候不是简单的将size置为0,而是将每个数组引用置为空,这也是以前说的实现自己的stack的时候防止内存泄露的需要注意的地方。

另外一个我觉得能从HashMap中学到的是它的构造函数的构造方式,里面提供了init方法(空实现)供子类覆盖,这就向子类提供了一个挂接的钩子,当然这个钩子是保证挂接之前map里面一些东西的初始化顺序的。实际上,很多框架的做法也是这样,很无敌。。。。

需要注意的是每个对象的hash值只要往map里面放了,就不能改变了,这从他们的定义可以看出来都是final的。

transfer函数做的无非是resize时将数组里的元素移动到另外一个新数组里,但是对象的hash值没变,变的只是对象在新数组中的位置(这个需要重新indexFor)。

其中remove和resize相关的操作其实主要就是链表的操作,只要熟练链表操作的代码,都不难看懂。

唯一比较困惑的地方是既然在同一位置的hash值一样,为什么很多比较操作比较的时候却又去比较hash值,这一点比较困惑,难道同一位置的元素hash值可能不同(原来位置的计算不是根据对象的hash来算的吗??)。

里面还有一个值得学习的地方是它的设计模式,用的真是炉火纯青啊。。。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics