`

cache 清除算法 LRU & LFU & FIFO

 
阅读更多

LRU:

LinkedHashMap ,

实现思路:HashMap + 双向链表环

按照最近访问/插入顺序,始终保持队列尾部的为最近访问或者最近插入的数据,删除从对头开始!

LinkedHashMap扩展如下方法即可:

 

protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
        return false;
    }

 

 

LFU:

实现思路:HashMap + PriorityQueue

下面是个根据Key的自然数据排序的案例(类似,可以把Key包装成一个可排序的包装类型,根据访问次数确定顺序):

 

import java.util.HashMap;
import java.util.PriorityQueue;

/**
 * 
 * @author xinchun.wang
 * @email: 532002108@qq.com
 */
public class LFUHashMap<K, V> {

	private static final int max_size = 10;

	HashMap<K, V> map = new HashMap<K, V>();

	PriorityQueue<Node<K>> tSet = new PriorityQueue<Node<K>>();

	@SuppressWarnings("unchecked")
	public V put(K key, V value) {
		if (map.size() > max_size) {
			Node<K> firstKey = (Node<K>) tSet.poll();
			map.remove(firstKey.getKey());
		}
		tSet.add(new Node(key, 1));
		return map.put(key, value);
	}

	public V get(Object key) {
		V result = map.get(key);
		incHit(key);
		return result;
	}

	private void incHit(Object key) {
		for (Object item : tSet) {
			if (((Node) item).key == key) {
				((Node) item).setCount(((Node) item).getCount() + 1);
				break;
			}
		}
	}

	@Override
	public String toString() {
		return map.toString();
	}

	public static void main(String[] args) {
		LFUHashMap<Integer, String> lfu = new LFUHashMap<Integer, String>();
		for (int i = 0; i < 100; i++) {
			lfu.put(i, String.valueOf(i) + "_data");
			if (i > 5) {
				lfu.get(1);
				lfu.get(2);
				lfu.get(3);
				lfu.get(4);
			}
			if (i > 10) {
				lfu.get(9);
			}
		}
		while (lfu.tSet.peek() != null) {
			System.out.println(lfu.tSet.poll());
		}
		System.out.println(lfu);
	}

	private static class Node<K> implements Comparable<Node<K>> {
		private K key;
		private int count;

		public Node(K key, int count) {
			this.key = key;
			this.count = count;
		}

		public K getKey() {
			return key;
		}

		public int getCount() {
			return count;
		}

		public void setCount(int count) {
			this.count = count;
		}

		@Override
		public String toString() {
			return "Node [key=" + key + ", count=" + count + "]";
		}

		@Override
		public int compareTo(Node<K> o) {
			int diff = this.count - o.count;
			return diff != 0 ? diff : -((Integer) o.key).compareTo((Integer) this.key);
		}

	}

}

 

 

FIFO:

仿照LinkedHashMap,通过LinkedList 就可以实现FIFO的元素排队

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics