LinkedHashMap源码分析(一)
来源:互联网 发布:淘宝装修店招全屏代码 编辑:程序博客网 时间:2024/06/10 06:40
LinkedHashMap 表示链散列映射表:继承了散列映射表HashMap,实现了Map接口。LinkedHashMap用的是访问顺序而不是插入顺序,对映射表条目进行迭代。每次调用get或put方法时,受到影响的条目都会被删除并放到链表的尾部(只有条目在链表中的位置会受影响,而散列表中的桶不会受到影响,一个条目总位于键散列码对应的桶中)。访问顺序有利于实现高速缓存的“最近最少使用”。例如,可能希望将访问频率搞得元素放在内存中,访问频率低的从数据库中读取。当表中找不到所需的元素项而表又满了,就可以将迭代器加入到表中,并将枚举的前几个元素删除。这些事近期最少使用的元素。这一过程可以自动化,只需要覆盖下面的方法:
protected boolean removeEldestEntry(Map.Entry eldest)
源码里面给了一个例子,可以缓存100个元素:
private static final int MAX_ENTRIES = 100; protected boolean removeEldestEntry(Map.Entry eldest) { return size() > MAX_ENTRIES; }每当方法放回true时,就添加一个新的条目,从而导致删除eldest条目。
这是为什么呢?看一下addEntry()方法就明白了:
void addEntry(int hash, K key, V value, int bucketIndex) { createEntry(hash, key, value, bucketIndex); // Remove eldest entry if instructed, else grow capacity if appropriate Entry<K,V> eldest = header.after; if (removeEldestEntry(eldest)) { removeEntryForKey(eldest.key); } else { if (size >= threshold) resize(2 * table.length); } }if(removeEldestEntry(eldest))巧妙的调用了removeEldestEntry方法。
在看一下LinkedHashMap的内部迭代器,感觉写的很好(对我来讲源码写的都很好):
private abstract class HashIterator<E> implements Iterator<E> { Entry<K,V> next;// next entry to return int expectedModCount;// For fast-fail int index;// current slot Entry<K,V> current;// current entry HashIterator() { expectedModCount = modCount; if (size > 0) { // advance to first entry Entry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } } public final boolean hasNext() { return next != null; } final Entry<K,V> nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); Entry<K,V> e = next; if (e == null) throw new NoSuchElementException(); if ((next = e.next) == null) { Entry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } current = e; return e; } public void remove() { if (current == null) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); Object k = current.key; current = null; HashMap.this.removeEntryForKey(k); expectedModCount = modCount; } }
expectedModCount 是迭代器内部的修改计数器,初始化的时候等于集合的modCount,当一个集合有多个迭代器时,会出现一个问题:就是迭代器a在对集合进行修改前已经有其他迭代器对集合进行了结构化修改,所以会导致两个计数器数值不一致,此时就会抛出ConcurrentModificationException同时修改异常。
0 0
- LinkedHashMap源码分析(一)
- LinkedHashMap源码分析(基于JDK1.6)
- LinkedHashMap源码分析(基于JDK1.6)
- HashMap LinkedHashMap源码分析
- LinkedHashMap源码分析
- LinkedHashMap源码分析
- LinkedHashMap源码分析
- LinkedHashMap源码分析
- LinkedHashMap源码分析
- 《Java源码分析》:LinkedHashMap
- LinkedHashMap及其源码分析
- LinkedHashMap源码分析
- LinkedHashMap及其源码分析
- LinkedHashMap源码分析
- LinkedHashMap源码分析
- LinkedHashMap源码分析
- LinkedHashMap及其源码分析
- 《Java源码分析》:LinkedHashMap
- 对话框
- spark性能调优之使用Kryo序列化
- [LeetCode]401. Binary Watch
- ubuntu 16.04安装字体
- 由.detectMultiScale()函数调试引起的异常问题的解决方案
- LinkedHashMap源码分析(一)
- 贪心POJ3069
- iOS的AssetsLibrary框架访问所有相片
- 谷歌离线地图发布服务器
- HDU 3722 Card Game
- 线程
- 什么是泛型?为什么要用泛型?什么是泛型擦除?泛型擦除的过程?
- 使用CSS相对单位构建可缩放的组件
- C++中字符串和数字相互转化实现