Java集合分析6
[toc]
散列
一般想法
每个key都能完美的映射到表中.
散列函数
不存在完美的映射, 需要一个高效的函数 p = f(key). f称为散列函数. 通常, 关键字是一个字符串, 散列函数需要很好的选择
- 把字符串中字符的ASCII码或UniCode码的值加起来
1 | //缺陷, 如果表很大, 函数将会不好分配, 例如key最多8个字符, 那么散列函数最多分配 127 * 8 = 1016 之间. |
- 一个稍微好的散列函数
1 |
|
Hornor 法则:有一些关于多项式求值的问题。对于多项式求值问题,我们最容易想到的算法是求出每一项的值然后把所求的值累加起来,这种算法的时间和空间效率都不高,对于数据规模不大的题目来说由于其直观、简单很容易被大家采纳,可一旦数据规模过大时,这种算法就显得无能为力了,下面介绍一种解决这类求值问题的高效算法――霍纳法则。在中国,霍纳法则也被称为秦九韶算法。
Java中HashCode的实现
1 | /** |
一个有趣的讨论
Why does Java’s hashCode() in String use 31 as a multiplier?
结论推测为早期的JVM优化31作为乘子可以优化 i* 31 = (i << 5) - i , 不过随着现代编译器的性能优化, 这个可能也不算是一个非常大的问题.
解决冲突: 分离链法
将散列到同一个值的所有元素保存到一个表中.

HashMap的源码解读
基本构成
1 | public class HashMap<K,V> extends AbstractMap<K,V> |
1 | //节点 理论上是一个链表中的节点. |
1 | //定义的一些常量 |
构造函数
1 | /** |
hash函数的原理解释, 可以参考hash函数的原理解读
1 | /** |
工具
1 | /** |
增
1 | /** |