Java集合之LinkedHashMap
2016-03-08 23:49
375 查看
我们在使用HashMap的过程中会发现一个问题,对于这个集合,我们好像没有办法让其按照我们想要的顺序输出。
针对这个需求,就诞生了LinkedHashMap。
LinkedHashMap集成了HashMap,然后有两个自己的独特成员:
LinkedList是一个双向链表,header是其头部,是一个初始化为-1的节点,这也是一个链表常见的技巧。
而这位accessOrder同学就是主角啦!
对LinkedHashMap初始化时,可以选择是否初始化这个成员,
View Code
上面看的是访问节点,那么添加节点呢?
直接继承HashMap的添加节点方法,但下面又调用了一个删除最老节点的操作,看一下:
咦?那这样不是永远都返回false么?哪还有什么意义?
当然有意义,我们可以重写这个函数,为期设定删除最老节点的条件,例如size()>100之类的。
到这里,应该就意识到了,这个LinkedHashMap好像可以实现鼎鼎大名的LRU缓存算法吧?答对了,不过这个在以后细说。
好了,LinkedHashMap的分析暂时就到这里。
针对这个需求,就诞生了LinkedHashMap。
LinkedHashMap集成了HashMap,然后有两个自己的独特成员:
private transient Entry<K,V> header; private final boolean accessOrder;
LinkedList是一个双向链表,header是其头部,是一个初始化为-1的节点,这也是一个链表常见的技巧。
void init() { header = new Entry<>(-1, null, null, null); header.before = header.after = header; }
而这位accessOrder同学就是主角啦!
对LinkedHashMap初始化时,可以选择是否初始化这个成员,
private static class Entry<K,V> extends HashMap.Entry<K,V> { // These fields comprise the doubly linked list used for iteration. Entry<K,V> before, after; Entry(int hash, K key, V value, HashMap.Entry<K,V> next) { super(hash, key, value, next); } /** * Removes this entry from the linked list. */ private void remove() { before.after = after; after.before = before; } /** * Inserts this entry before the specified existing entry in the list. */ private void addBefore(Entry<K,V> existingEntry) { after = existingEntry; before = existingEntry.before; before.after = this; after.before = this; } /** * This method is invoked by the superclass whenever the value * of a pre-existing entry is read by Map.get or modified by Map.set. * If the enclosing Map is access-ordered, it moves the entry * to the end of the list; otherwise, it does nothing. */ void recordAccess(HashMap<K,V> m) { LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m; if (lm.accessOrder) { lm.modCount++; remove(); addBefore(lm.header); } } void recordRemoval(HashMap<K,V> m) { remove(); } }
View Code
上面看的是访问节点,那么添加节点呢?
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); } }
直接继承HashMap的添加节点方法,但下面又调用了一个删除最老节点的操作,看一下:
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { return false; }
咦?那这样不是永远都返回false么?哪还有什么意义?
当然有意义,我们可以重写这个函数,为期设定删除最老节点的条件,例如size()>100之类的。
到这里,应该就意识到了,这个LinkedHashMap好像可以实现鼎鼎大名的LRU缓存算法吧?答对了,不过这个在以后细说。
好了,LinkedHashMap的分析暂时就到这里。
相关文章推荐
- Java 模拟Ajax上传文件
- Java 函数的参数说
- Java Memory Model基础
- Java中的String为什么是不可变的?
- 深入理解Java内存模型
- 【Eclipse】2、使用eclipse软件编译并执行代码
- Eclipse中配置javah命令自动生成JNI头文件
- leedCode 335 Self Crossing
- Spring JDBC的CRUD方法详解
- IT十八掌作业_java基础第九天_多线程、自动拆装箱
- 【Eclipse】1、eclipse软件下载
- spring security简单实例
- Eclipse 的使用
- leedCode 292 Nim Game 解题
- java中形参String的可变参数的定义(String...)
- 框架基础——全面解析Java注解
- Java Immutable不可变类
- Java Spring
- Java线程第二弹--资源冲突问题
- Java中的ExceptionInInitializerError 异常解决方法