LinkedHashMap源码解析
程序员文章站
2022-05-06 08:46:55
...
数据结构
继承于HashMap结构,
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
- 按照插入顺序进行访问
- 实现了访问最少最先删除功能,其目的是把很久没有访问的key删除
常见属性
/**
* 链表头
*/
transient LinkedHashMap.Entry<K,V> head;
/**
* 链表尾
*/
transient LinkedHashMap.Entry<K,V> tail;
/**
* 控制两种访问模式的字段,默认false
* true 按照访问顺序
* false 按照插入顺序
*/
final boolean accessOrder;
操作
按照添加顺序新增
LinkedHashMap继承了HashMap,重写了put方法中的newNode、newTreeNode、afterNodeAccess方法
//新增节点,并追加到链表尾部
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
LinkedHashMap.Entry<K,V> p =
new LinkedHashMap.Entry<K,V>(hash, key, value, e);
linkNodeLast(p);
return p;
}
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
LinkedHashMap.Entry<K,V> last = tail;
tail = p;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
}
访问最少删除策略
public void testAccessOrder() {
// 新建 LinkedHashMap
LinkedHashMap<Integer, Integer> map = new LinkedHashMap<Integer, Integer>(4,0.75f,true) {
{
put(10, 10);
put(9, 9);
put(20, 20);
put(1, 1);
}
@Override
// 覆写了删除策略的方法,我们设定当节点个数大于 3 时,就开始删除头节点
protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
return size() > 3;
}
};
log.info("初始化:{}",JSON.toJSONString(map));
Assert.assertNotNull(map.get(9));
log.info("map.get(9):{}",JSON.toJSONString(map));
Assert.assertNotNull(map.get(20));
log.info("map.get(20):{}",JSON.toJSONString(map));
}
public V get(Object key) {
Node<K,V> e;
if ((e = getNode(hash(key), key)) == null)
return null;
//如果设置了LRU策略
if (accessOrder)
//这个方法把当前key移动到队尾
afterNodeAccess(e);
return e.value;
}
这个里实现了put的时候的删除操作
void afterNodeInsertion(boolean evict) { // possibly remove eldest
LinkedHashMap.Entry<K,V> first;
if (evict && (first = head) != null && removeEldestEntry(first)) {
K key = first.key;
removeNode(hash(key), key, null, false, true);
}
}
总结
LinkedHashMap提供了按照插入顺序访问和删除最小访问元素策略,通过链表就实现了
上一篇: 高并发那些事
推荐阅读
-
使用Flume+Kafka+SparkStreaming进行实时日志解析
-
nginx-【php-fpm的安装】源码安装php-fpm,最后找不到php-fpm文件
-
深入解析C++和JAVA的字符串
-
深入解析fsockopen与pfsockopen的区别_PHP教程
-
php中使用parse_url对网址进行解析的实现代码parse_url详解
-
javascript - 有没有能解析js的库啊?
-
解析argc argv在php中的应用
-
源码安装memcached和php memcache扩展
-
区位码输入法 PHP中实现汉字转区位码应用源码实例解析
-
深入解析JavaScript中的变量作用域_javascript技巧