HashMap
HashMap的扩容机制?
如果Entry的数量达到或者超过阈值即(size >= threshold,并且将要插入的数组位置不为空,即null != table[bucketIndex],将table数组的长度增加为原来的2倍即resize(2 * table.length),并且计算新的位置bucketIndex = indexFor(hash, table.length)。
Entry节点插入机制?
通过扩容处理之后,调用createEntry(),将节点采用头插法插入到table数组指定位置中。
源代码:
void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}
void createEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
size++;
}
数据结构:
LinkedHashMap的扩容和插入机制与HashMap的实现机制相同,super.addEntry(hash, key, value, bucketIndex);
以下内容部分来源:http://zhangshixi.iteye.com/blog/673789
源代码:
void addEntry(int hash, K key, V value, int bucketIndex) {
super.addEntry(hash, key, value, bucketIndex);
// Remove eldest entry if instructed
Entry<K,V> eldest = header.after;
if (removeEldestEntry(eldest)) {
removeEntryForKey(eldest.key);
}
}
数据结构
上图显示了LinkedHashMap的链表部分数据结构,数组部分的数据结构和hashMap相同,仍然是一个table[bucketIndex];。
总而言之,其实LinkedHashMap几乎和HashMap一样,不同的是它定义了一个Entry<K,V> header,这个header不是放在Table里,它是额外独立出来的,如图所示。LinkedHashMap通过继承hashMap中的Entry<K,V>,并添加两个属性Entry<K,V> before,after,和header结合起来组成一个双向链表,来实现按插入顺序或访问顺序排序。
排序模式:
LinkedHashMap定义了排序模式accessOrder,该属性为boolean型变量。
- 对于访问顺序,为accessOrder=true,即采用LRU策略:按从近期访问最少到近期访问最多的顺序重排序。
- 对于插入顺序,则为accessOrder=false。
一般情况下,不必指定排序模式,其迭代顺序即为默认为插入顺序。看LinkedHashMap的构造方法,如:
public LinkedHashMap(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
accessOrder = false;
}
如果你想按照访问顺序构造一个LinkedHashMap,调用重构的构造函数:
public LinkedHashMap(int initialCapacity,
float loadFactor,
boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
缓存模式:
接下来的代码用来更新缓存,调用removeEldestEntry方法,这里就是实现LRU元素过期机制的地方,默认的情况下removeEldestEntry方法只返回false表示元素永远不过期。
重写removeEldestEntry方法,维持此映射只保存100个条目的稳定状态,在每次添加新条目时删除最旧的条目。
private static final int MAX_ENTRIES = 100;
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_ENTRIES;
}
基于LinkedHashMap实现LRU缓存调度算法原理 http://blog.csdn.net/langjian2012/article/details/45184303
修改部分内容参考自:http://www.cnblogs.com/children/archive/2012/10/02/2710624.html