说了这么多,Java 下到底如何实现Cache,希望下面的实际案例可以帮助到你。 public class CacheFactory private static ConcurrentHashMap caches = new ConcurrentHashMap(); private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); private static void register(Cache cache) caches.put(cache.category(), cache); private static void registerAll() register(new StockCache()); public static void init() registerAll(); for (Cache cache : caches.values()) executorService.scheduleAtFixedRate(new Runnable() @Override public void run() cache.refresh(); , 0, cache.interval(), TimeUnit.MILLISECONDS); public static Cache getCache(String key) if (caches.contains(key)) return caches.get(key); return null; // cache接口除了需要提供interval和refresh以外,还需要提供一个category来区分不同的Cache public interface Cache /** * Refresh the cache. If succeed, return true, else return false; * * @return */ boolean refresh(); /** * How much time it will refresh the cache. * * @return */ long interval(); /** * Cache's category. Each cache has distinct category. * * @return */ String category();
java 146. LRU Cache(#)。java
/*
Using Single Linked List. Store the Previous Node in the HashMap
1. When get the last element, will remove the Node first, then move it to the tail
the tail Pointer should be set to previous Node
2. When delete one Node, update the previous of the cur.next Node in the HashMap
3. WHen move one Node to the tail, update the cur Node in the HashMap and set the cur.next to NULL
*/
public class LRUCache {
private class Node {
Node next;
int key;
int val;
public Node(int key, int val) {
this.key = key;
this.val = val;
this.next = null;
}
}
private int capacity;
private HashMap<Integer, Node> map;
private Node head = new Node(-1, -1);
private Node tail = new Node(-1, -1);
public LRUCache(int capacity) {
this.capacity = capacity;
map = new HashMap<Integer, Node>();
tail = head;
}
public int get(int key) {
if(!map.containsKey(key)) {
return -1;
}
Node pre = map.get(key);
Node cur = pre.next;
moveToTail(pre, cur);
return cur.val;
}
public void put(int key, int value) {
if(map.containsKey(key)) {
//map.get(key).val = value;
Node pre = map.get(key);
Node cur = pre.next;
cur.val = value;
moveToTail(pre, cur);
return;
}
if(map.size() == capacity) {
map.remove(head.next.key);
head.next = head.next.next;
if(head.next != null) {
map.put(head.next.key, head);
} else {
tail = head;
}
}
Node cur = new Node(key, value);
map.put(key, tail);
tail.next = cur;
tail = cur;
}
private void moveToTail(Node pre, Node cur) {
pre.next = cur.next; // remove cur from the list first
if(cur.next == null) {
tail = pre;
} else {
map.put(cur.next.key, pre);
}
tail.next = cur;
cur.next = null;
map.put(cur.key, tail);
tail = cur;
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
public class LRUCache {
private class Node {
Node pre;
Node next;
int key;
int val;
public Node(int key, int val) {
this.key = key;
this.val = val;
this.pre = null;
this.next = null;
}
}
private int capacity;
private HashMap<Integer, Node> map;
private Node head = new Node(-1, -1);
private Node tail = new Node(-1, -1);
public LRUCache(int capacity) {
this.capacity = capacity;
map = new HashMap<Integer, Node>();
head.next = tail;
tail.pre = head;
}
public int get(int key) {
if(!map.containsKey(key)) {
return -1;
}
Node cur = map.get(key);
//move the current Node to tail
cur.next.pre = cur.pre;
cur.pre.next = cur.next;
tail.pre.next = cur;
cur.pre = tail.pre;
tail.pre = cur;
cur.next = tail;
return cur.val;
}
public void put(int key, int value) {
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
/*
["LRUCache","put","put","get","put","get","put","get","get","get"]
[[2],[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]]
["LRUCache","put","put","put","put","get","get"]
[[2],[2,1],[1,1],[2,3],[4,1],[1],[2]]
*/
class LRUCache {
class ListNode {
int key;
int val;
ListNode prev;
ListNode next;
public ListNode (int key, int val) {
this.key = key;
this.val = val;
this.prev = null;
this.next = null;
}
}
int capacity;
ListNode head;
ListNode tail;
Map<Integer, ListNode> map;
public LRUCache(int capacity) {
this.capacity = capacity;
head = new ListNode(-1, -1);
tail = new ListNode(-1, -1);
head.next = tail;
tail.prev = head;
map = new HashMap<>();
}
public int get(int key) {
if (!map.containsKey(key)) return -1;
ListNode cur = map.get(key);
delink_node(cur);
move_to_tail(cur);
return cur.val;
}
public void put(int key, int value) {
if (map.containsKey(key)) {
ListNode cur = map.get(key);
cur.val = value;
delink_node(cur);
move_to_tail(cur);
return;
}
if (map.size() == capacity) {
ListNode cur = head.next;
delink_node(cur);
map.remove(cur.key);
}
ListNode cur = new ListNode(key, value);
map.put(key, cur);
move_to_tail(cur);
return;
}
private void delink_node(ListNode cur) {
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
}
private void move_to_tail(ListNode cur) {
ListNode prev = tail.prev;
prev.next = cur;
cur.prev = prev;
cur.next = tail;
tail.prev = cur;
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/