LinkedHashMap
这是一个继承自HashMap的类,在类说明中,这是一个非同步的,不能在多线程环境下使用,否则要自己实现同步.有两种模式,一种是元素访问的次数排序,一种是插入的时间排序
Linked内部含有一个private transient Entry header;来记录元素插入的顺序或者是元素被访问的顺序。
正如 LinkedHashMap的文档所说,LinkedHashMap简直就是为了实现LRU Cache(Least Recently Used)而编写的。正因为如此,在oscache或者是ehcache都使用到了LinkedHashMap。(oscache中是否使用LRU是可以配置的)
那么,这是如何实现的呢,见源码如下:
public V get(Object key) {
Entry<K,V> e = (Entry<K,V>)getEntry(key);
if (e == null)
return null;
e.recordAccess(this);
return e.value;
}
这是取值的代码,请看得到实体的代码:
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
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;
}
return null;
}
完全是从hashMap中得到实体对象,根据key.
这里调用了recordAccess方法,然后再返回value.请看:
void recordAccess(HashMap<K,V> m) {
LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
if (lm.accessOrder) {
lm.modCount++;
remove();
addBefore(lm.header);
}
}
如果accessOrder实true,那是是访问排序,如果为false则为插入排序。
transient volatile int modCount;
这个参数可以用来标识修改次数,也可以用来标识访问次数
private void remove() {
before.after = after;
after.before = before;
}
从列表上移除该对象.
private void addBefore(Entry<K,V> existingEntry) {
after = existingEntry;
before = existingEntry.before;
before.after = this;
after.before = this;
}
把这个对象添加到第一个.