1 2 3 4 | // Callbacks to allow LinkedHashMap post-actions void afterNodeAccess(Node<K,V> p) { } void afterNodeInsertion(boolean evict) { } void afterNodeRemoval(Node<K,V> p) { } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | //移除节点的回调函数 void afterNodeRemoval(Node<K,V> e) { // unlink //移除一个节点,双向链表中的连接关系也要调整 LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after; p.before = p.after = null; if (b == null) head = a; else b.after = a; if (a == null) tail = b; else a.before = b; } //插入节点的回调函数 //构造函数中调用,evict为false void afterNodeInsertion(boolean evict) { // possibly remove eldest LinkedHashMap.Entry<K,V> first; //first是头元素,也是最老的元素 //在插入序中,就是最先插入的元素 //在访问序中,就是最远被访问的元素 //这里removeEldestEntry(first)始终返回true,即不删除最老的元素 //如果是一个容量固定的cache,可调整removeEldestEntry(first)的实现 if (evict && (first = head) != null && removeEldestEntry(first)) { //不是构造方法中 //头元素不为空 //要删除最老的元素 //在LinkedHashMap的实现中,不会进入这里 K key = first.key; removeNode(hash(key), key, null, false, true); } } //访问节点的回调函数 void afterNodeAccess(Node<K,V> e) { // move node to last LinkedHashMap.Entry<K,V> last; //如果是访问序,且当前节点并不是尾节点 //将该节点置为双向链表的尾部 if (accessOrder && (last = tail) != e) { //p 当前节点, b 前驱结点, a 后继结点 LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after; p.after = null; //设为尾节点,则没有后继 if (b == null) head = a; //p是头节点,调整后其后继结点变为头节点 else b.after = a;//p不是头节点,前驱和后继结点相连 if (a != null) a.before = b; else last = b;//应该不会出现这种情况,p是尾节点 if (last == null) head = p; else { //将p置于尾节点之后 p.before = last; last.after = p; } tail = p;//调整tail指向 ++modCount;//结构性改变 } } |
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |