知识大全 java.util.HashMap源码要点浅析
Posted 知
篇首语:没关系,天空越黑,星星越亮。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 java.util.HashMap源码要点浅析相关的知识,希望对你有一定的参考价值。
java.util.HashMap源码要点浅析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
散列表要解决的一个问题就是散列值的冲突问题 通常是两种方法 链表法和开放地址法 链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位 开放地址法是通过一个探测算法 当某个槽位已经被占据的情况下继续查找下一个可以使用的槽位 java util HashMap采用的链表法的方式 链表是单向链表 因此在删除过程中要自己维持prev节点 我想不采用双向链表是从节省空间考虑 一个典型的查找过程
for (Entry<K V> e = table[indexFor(hash table length)]; e != null; e = e next) Object k; if (e hash == hash && ((k = e key) == key || (key != null && key equals(k)))) return e;
HashMap采用链表法而不是开放地址法 猜想可能的原因是从实用角度出发 对空间和时间效率做出的折中选择 采用开放地址法 无论是线性探测或者二次探测都可能造成群集现象 而双重散列会要求散列表的装填程度比较低的情况下会有比较好的查找效率 容易造成空间的浪费
什么是负载因子?负载因子a定义为
a=散列表的实际元素数目(n)/ 散列表的容量(m)
负载因子衡量的是一个散列表的空间的使用程度 负载因子越大表示散列表的装填程度越高 反之愈小 对于使用链表法的散列表来说 查找一个元素的平均次数是 ( +a)次 因此如果负载因子越大 对空间的利用更充分 然而后果是查找效率的降低 如果负载因子太小 那么散列表的数据将过于稀疏 对空间造成严重浪费
回到HashMap的实现 HashMap中的loadFactor其实定义的就是该map对象允许的最大的负载因子 如果超过这个系数将重新resize 这个是通过threshold字段来判断 看threshold的计算
threshold = (int)(capacity * loadFactor);
结合上面的负载因子的定义公式可知 threshold就是在此loadFactor和capacity对应下允许的最大元素数目 超过这个数目就重新resize 以降低实际的负载因子 默认的的负载因子 是对空间和时间效率的一个平衡选择 注意到的一点是resize的规模是现有 capacity的两倍
if (size++ >= threshold) resize( * table length);
可能你也注意到了 java util HashMap对key的hash值多做了一步处理 而不是直接使用hashCode
static int hash(int h) h ^= (h >>> ) ^ (h >>> ); return h ^ (h >>> ) ^ (h >>> );
这个处理的原因在于HashMap的容量总是采用 的p次幂 而取index(槽位)的方法是
static int indexFor(int h int length) return h & (length );
这一运算等价于对length取模 也就是
h % ^p
返回的将是h的p个最低位组成的数字 我们假设hash输入是符合简单一致散列 然而这一假设并不能推论出hash的p个最低位也会符合简单一致散列 也许h的这p个最低位相同的几率很大 那么冲突的几率就非常大了 优秀的散列函数应该需要考虑所有的位
因此为了防止这些 坏 的散列函数造成效率的降低 HashMap预先对hash值做了处理以考虑到所有的位 根据注释也可以知道 这个处理我看不懂 留待高人解释 也许来自于某本算法书也不一定
我们知道java util HashMap不是线程安全的 因此如果在使用迭代器的过程中有其他线程修改了map 那么将抛出ConcurrentModificationException 这就是所谓fail fast策略(速错) 这一策略在源码中的实现是通过 modCount域 modCount顾名思义就是修改次数 对HashMap内容的修改都将增加这个值 那么在迭代器初始化过程中会将这个值赋给迭代器的expectedModCount
HashIterator() expectedModCount = modCount; if (size > ) // advance to first entry Entry[] t = table; while (index < t length && (next = t[index++]) == null) ;
在迭代过程中 判断modCount跟expectedModCount是否相等 如果不相等就表示已经有其他线程修改了map
注意到modCount声明为volatile 保证线程之间修改的可见性 cha138/Article/program/Java/JSP/201311/19501相关参考
一、安全操作1、拖拉机田间作业操作⑴驾驶员必须经农机培训学校技术培训,并取得大中型拖拉机驾驶证;拖拉机必须取得行驶证和牌照。⑵驾驶员在开车前后,要严格做好检查、保养工作。拖拉机必须保持技术状态正常,避
一、安全操作1、拖拉机田间作业操作⑴驾驶员必须经农机培训学校技术培训,并取得大中型拖拉机驾驶证;拖拉机必须取得行驶证和牌照。⑵驾驶员在开车前后,要严格做好检查、保养工作。拖拉机必须保持技术状态正常,避
中耕除草根据笔者多年的观察,除草剂代替人工除草,对玉米影响不大。玉米除草剂主要有:除草剂单剂和除草剂混剂两种。 1、除草剂单剂除草技术第一种是酰胺类除草剂:在杂草发芽前进行土壤封闭处理,能有效防治一
中耕除草根据笔者多年的观察,除草剂代替人工除草,对玉米影响不大。玉米除草剂主要有:除草剂单剂和除草剂混剂两种。 1、除草剂单剂除草技术第一种是酰胺类除草剂:在杂草发芽前进行土壤封闭处理,能有效防治一
在农机维修中,装配是十分重要的工序。而装配质量则直接决定农机的使用寿命、经济性和技术性能。因此,在农机维修中必须重视装配环节。现将其技术要点阐述如下:1.装配前对各装配件应进行仔细清洗。装配过程中,应
在农机维修中,装配是十分重要的工序。而装配质量则直接决定农机的使用寿命、经济性和技术性能。因此,在农机维修中必须重视装配环节。现将其技术要点阐述如下:1.装配前对各装配件应进行仔细清洗。装配过程中,应
1要点在鱼类受到低溶氧综合症应激时,鱼类对氧气的需求量增加,随着鱼类氧气消耗量的增加,产生二氧化碳的量也增加,使得鱼类血液输送氧气的能力下降。鱼类处于低氧综合症环境条件下,生长减弱,组织受损或坏死,对
1要点在鱼类受到低溶氧综合症应激时,鱼类对氧气的需求量增加,随着鱼类氧气消耗量的增加,产生二氧化碳的量也增加,使得鱼类血液输送氧气的能力下降。鱼类处于低氧综合症环境条件下,生长减弱,组织受损或坏死,对
ASP调用存储过程源码示例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! ASP调用存储过程源码
PHP源码---页面快速转向 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! <?