it_worker365

   ::  ::  ::  ::  :: 管理

1. 基于LinkedHashMap

2. 基于HashMap 和 双向链表

import java.util.LinkedHashMap;

/**
 * Created by itworker365 on 5/11/2017.
 * 基于LinkedHashMap特性,用继承或代理方式,选择基于访问顺序并在继承后重写removeEldestEntry当超过容量时返回true。
* 基本测试看代码知道这个结构的实现就很清楚了,不用写了。
*/ public class LRUCacheUseLinkedHashmap { public static void main(String[] args) { /** * LinkedHashMap 参数说明 * initialCapacity the initial capacity * loadFactor the load factor * accessOrder the ordering mode - <tt>true</tt> for access-order, <tt>false</tt> for insertion-order */ LinkedHashMap<Integer, Integer> linkedHashMapInsertionOrder = new LinkedHashMap<>(5, 10, false); linkedHashMapInsertionOrder.put(1, 111); linkedHashMapInsertionOrder.put(3, 333); linkedHashMapInsertionOrder.put(2, 222); System.out.println("linkedHashMapInsertionOrder before get: " + linkedHashMapInsertionOrder.toString()); linkedHashMapInsertionOrder.get(3); System.out.println("linkedHashMapInsertionOrder after get: " + linkedHashMapInsertionOrder.toString()); LinkedHashMap<Integer, Integer> linkedHashMapAccessOrder = new LinkedHashMap<>(5, 10, true); linkedHashMapAccessOrder.put(1, 111); linkedHashMapAccessOrder.put(3, 333); linkedHashMapAccessOrder.put(2, 222); System.out.println("linkedHashMapAccessOrder before get: " + linkedHashMapAccessOrder.toString()); linkedHashMapAccessOrder.get(1); System.out.println("linkedHashMapAccessOrder after get: " + linkedHashMapAccessOrder.toString()); linkedHashMapAccessOrder.put(4, 444); System.out.println("linkedHashMapAccessOrder put: " + linkedHashMapAccessOrder.toString()); } }
import java.util.HashMap;

/**
 * Created by itworker365 on 5/11/2017.
 */
public class LRUCache {
    int capacity;
    HashMap<Integer, Entry> table = new HashMap<Integer, Entry>();
    Entry head = null;
    Entry tail = null;

    public LRUCache(int capacity) {
        this.capacity = capacity;
    }

    public int get(int key) {
        if (table.containsKey(key)) {
            Entry entry = table.get(key);
            //调整节点位置
            NodeChangeAfterAccess(entry);
            return entry.value;
        } else {
            return -1;
        }
    }

    public void set(int key, int value) {
        if(table.containsKey(key)){
            //已经存在节点,则取出更新其value
            Entry old = table.get(key);
            old.value = value;
            //调整节点位置
            NodeChangeAfterAccess(old);
        }else{
            Entry created = new Entry(key, value, null, null);
            //LRU删除队尾元素
            if(table.size() >= capacity){
                table.remove(tail.key);
                removeNodeFromList(tail);
                MoveNodeToHead(created);
            }else{
                MoveNodeToHead(created);
            }
            table.put(key, created);
        }
    }

    private void NodeChangeAfterAccess(Entry old) {
        removeNodeFromList(old);
        MoveNodeToHead(old);
    }

    private void MoveNodeToHead(Entry entry) {
        //移动节点到头节点
        entry.next = head;
        entry.pre = null;
        if(head!=null) {
            head.pre = entry;
        }
        head = entry;
        if(tail ==null) {
            tail = head;
        }
    }

    private void removeNodeFromList(Entry entry) {
        //获取后需要调整链表关系除当前位置
        if (entry.pre != null) {
            entry.pre.next = entry.next;
        } else {
            head = entry.next;
        }
        if (entry.next != null) {
            entry.next.pre = entry.pre;
        } else {
            tail = entry.pre;
        }
    }
}
class Entry {
    int key;
    int value;
    Entry pre;
    Entry next;
    public Entry(int key, int value, Entry pre, Entry next) {
        this.key = key;
        this.value = value;
        this.pre = pre;
        this.next = next;
    }
}

 

posted on 2017-05-11 10:21  it_worker365  阅读(190)  评论(0编辑  收藏  举报