文章目录
1.图解LinkedHashmap
图解LinkedHashmap请看此文章,写的非常详细!:
图解LinkedHashMap原理
2.常见面试题:
2.1 LinkedHashMap基本原理
答:
- LinkedHashMap继承HashMap,基于HashMap+双向链表实现。(HashMap是数组+链表+红黑树实现的)
- LinkedHashMap是有序的,有两种顺序:插入顺序和访问顺序。默认为插入顺序,如果为访问顺序,那么put和get已存在的节点时,会将该节点移动到双向链表的尾部(实际上是先删后插)
- 插入顺序和访问顺序的转换是定义accessOrder参数的值,默认为false,为true则表示为访问顺序
- LinkedHashMap与HashMap的存取数据操作基本是一致的,只是增加了双向链表保证数据的有序性
- LinkedHashMap与HashMap都是线程不安全的。
2.2 LinkedHashMap如何实现LRU?
答:
- 定义LRULinkedHashMap继承LinkedHashMap,并重写removeEldestEntry()方法,这个方法返回boolean值,返回true代表需要删除最老的节点
- 要注意的就是创建实例对象的时候需要传入size和accessOrder参数(accessOrder= ture)
后面会有详细的实现
2.3 LinkedHashMap有几种顺序?
答:
- 两种顺序:插入顺序和访问顺序,通过创建实例对象时定义accessOrder参数的值来进行转换。默认为false,为插入顺序。
- 如果设置为访问顺序,那么put和get已存在的节点时,会将该节点移动到双向链表的尾部(实际上是先删后插)
3.LRU实现
public class LRULinkedHashMap<K,V> extends LinkedHashMap{
//缓冲容量
private int capacity;
public LRULinkedHashMap(int capacity){
super(16,0.75f,true);
this.capacity = capacity;
}
//重写removeEldestEntry 返回值代表是否需要删除最老的节点的判断
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
boolean sign = size() > capacity;
if(sign){
System.out.println("要删除地是:"+eldest);
}
return sign;
}
}
测试如下:
public static void main(String[] args) {
LRULinkedHashMap<String,Integer> map = new LRULinkedHashMap(4);
map.put("111",111);
map.put("222",222);
map.put("333",333);
map.put("444",444);
map.put("555",555);
Iterator<Map.Entry<String,Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String,Integer> entry = iterator.next();
System.out.println(entry.getKey()+ "=="+ entry.getValue());
}
}
输出如下:可以看到当容量大于4的时候,会删除最先插入的111
要删除地是:111=111
222==222
333==333
444==444
555==555