2013 1027:
类:
java.util.HashMap
属性:
table、size、threshold、loadFactor
笔记:
table是一个Entry数组,这个数组的长度,或者为0,或者是2的幂次方。
size是table中存储的实际的Entry数量,由于HashMap.Entry设计为链表节点,所以size是数组上所有节点链表的全部数据量。
threshold是扩容阈值,当size达到threshold的时候,并且在添加数据时,产生了hash碰撞时,就会触发扩容。每次扩容,table长度翻番。
loadFactor是扩容因子,基本上,threshold=table.size() * loadFactor 。默认值为0.75 。
类:
java.util.HashMap
方法:
void resize(int newCapacity)、private void inflateTable(int toSize)、private static int roundUpToPowerOf2(int number)
笔记:
前两个方法对table进行扩容。resize发生在新增元素时,直接扩容为两倍;inflateTable发生在初始化HashMap时,利用roundUpToPowerOf2方法计算防止number个元素,需要多大的table(长度为2的幂次)。
类:
java.util.HashMap
方法:
void createEntry(int hash, K key, V value, int bucketIndex)
笔记:
添加元素的统一方法。如果没有发生hash碰撞,直接将元素塞进table表。如果有碰撞,将新元素插在链表头。
类:
java.util.HashMap$KeySet、java.util.HashMap$Values、java.util.HashMap$EntrySet
笔记:
作为非静态内部类,这三个类共享着HashMap对象的全部数据,封装出各种相应的方法。
值得注意的是,他们的父类AbstractSet和AbstractCollection,对add方法的默认实现都是直接抛出UnsupportedOperationException异常,而这三个类,并没有去覆盖这个方法。显然,他们都不支持添加动作。
类:
java.util.HashMap$HashIterator
笔记:
这个抽象类很轻松的实现了HashMap.Entry的迭代,而它的子类EntryIterator、KeyIterator、ValueIterator则分别取出Entry中的不同数据,进行输出。
值得注意的是,HashIterator的remove方法会执行删除动作,而它的三个子类并没有改写该方法,所以三个子类进行迭代时,删除动作是一致的,就是删除一个映射项。
类:
java.util.HashMap
方法:
final int hash(Object k)、final boolean initHashSeedAsNeeded(int capacity)
笔记:
HashMap的核心方法,不允许继承。initHashSeedAsNeeded在每次table长度发生变化时重新生成hashSeed。hash方法计算一个对象应该放在table的什么位置。原理肯定是比较复杂的,但从功能上来看,作用就是减少hash碰撞,提高访问速度。