对LinkedHashMap的理解
来源:互联网 发布:淘宝推广pid 编辑:程序博客网 时间:2024/04/29 18:18
- 最初的认识:
- 可以维护元素的插入顺序,按照插入顺序遍历;
- 实现原理:LinkedHashmap的Entry除了该节点的hash值、key值、value值、next指向冲突时的后一个节点,还增加了指向前一个节点和后一个节点的指针:before、after,从而构成双向链表;除此之外,还有双向链表的头结点head和尾节点tail;
- LinkedHashMap的具体实现:
- 节点:
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); } }
- 头指针和尾指针:使用了transient关键字,该字段不进行序列化
transient LinkedHashMap.Entry<K,V> head;
transient LinkedHashMap.Entry<K,V> tail;
- 元素的两种顺序:插入顺序、访问顺序(accessorder,可以用于实现LRU cache);
- 插入顺序:遍历LinkedHashMap时,按照元素插入的顺序输出,put时,新元素追加在链表的尾部即可;
- 访问顺序:创建LinkedHashMap时,传入参数accessorder指定为true,即表示按照访问顺序遍历数组;此刻,头部是最久未被访问的节点,尾部是最近刚访问过的节点;
- get,如果该元素存在,则将节点从原位置删除,插入尾部;
- put:如果新插入的元素key已存在,则替换其value,并将它从原位置删除,再插入尾部,如果不存在,则直接插入尾部;
- 方法:removeEldestEntry
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { return false;}
重写该方法,可以指定在put元素时删除最久未被访问的,即双向链表头部的节点,从而实现LRU cache,默认不会删除。
- 节点:
- LinkedHashmap的遍历
- 使用EntrySet和迭代器;该例子中使用访问顺序,所以get操作会改变节点的顺序;
public static void main(String[] args) {LinkedHashMap<String,Integer> map = new LinkedHashMap<String,Integer>(16,(float) 0.75,true);map.put("er", 1);map.put("rt", 2);map.put("ui", 3);map.put("op", 4);map.get("er");map.get("ui");Set<Entry<String, Integer>> set = map.entrySet();Iterator<Entry<String, Integer>> itr = set.iterator();while(itr.hasNext()){Entry<String,Integer> ele = itr.next();System.out.println(ele.getKey()+" "+ele.getValue());}}
- 如果使用下面这种方式遍历,就会抛异常;
public static void main(String[] args) {LinkedHashMap<String,Integer> map = new LinkedHashMap<String,Integer>(16,(float) 0.75,true);map.put("er", 1);map.put("rt", 2);map.put("ui", 3);map.put("op", 4);Set<String> keyset = map.keySet();Iterator itr = keyset.iterator();while(itr.hasNext()){System.out.println(map.get(itr.next()));}}
1Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.LinkedHashMap$LinkedHashIterator.nextNode(Unknown Source)at java.util.LinkedHashMap$LinkedKeyIterator.next(Unknown Source)at 验证例子.LinkedListTest.main(LinkedListTest.java:28)
这是因为,new LinkedHashMap时,若指定accessorder为true,则get方法会调用afterNodeAccess方法,改变元素的位置,将其插入尾部,同时modCount++,所以调用Iterator 的next时,发现expectedModCount和modCount不一样,抛出ConcurrentModificationException;这是同步容器类的fail-fast机制;
- 使用LinkedHashMap实现LRU cache
- 关键是重写上面提到的removeEldestEntry方法
- 参考链接:http://www.open-open.com/lib/view/open1410490776680.html
0 0
- 对LinkedHashMap的理解
- 对LinkedHashMap的理解
- 【记】LinkedHashMap的理解
- LinkedHashMap的学习与理解
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- 理解LinkedHashMap
- LinkedHashMap学习理解
- 立体页面切换
- 陆维家具设计拆单软件
- 3种方法实现UILabel的左上角对齐显示文字
- [HDU1789]-Doing Homework again
- Android怎样播放多张图片形成一个动画
- 对LinkedHashMap的理解
- git安装与使用提交到github
- 泛型超详细解读(二):super和extend
- UVA10300 - Ecological Premium
- httpclient4下载图片 java实现
- #411 Gray Code
- Android-高通代码接触初篇
- jdbcTemplate获取mysql的blob
- chrome浏览器调试JS代码