首页

定义LFUCache类实现最不经常使用页置换LFU算法代码缓存代码示例

标签:LFU,缓存算法,页置换算法,lfu,最新最多使用优先,最少最早使用淘汰     发布时间:2019-06-22   

一、前言

不同于之前LRU缓存算法,LFU(全称是Least Frequently Used)即最不经常使用页置换算法,当到达存储上限时,优先淘汰最早最少访问的对象元素。

二、代码示例

package com.xwood.gw.accesslog;@b@@b@import java.util.Collections;@b@import java.util.HashMap;@b@import java.util.Map;@b@ @b@public class LFUCache<k,v> {@b@	@b@	  private final int capcity;@b@@b@	  private Map<k, v> cache = new HashMap<k, v>();@b@@b@	  private Map<k, HitRate> count = new HashMap<k,HitRate>();@b@@b@	  public LFUCache(int capcity) {@b@	    this.capcity = capcity;@b@	  }@b@	  @b@	  public  boolean containKey(k keyObj){@b@		  return  cache.keySet().contains(keyObj);@b@	  }@b@	  @b@	  public  boolean  containValue(v valueObj){@b@		  return cache.entrySet().contains(valueObj);@b@	  }@b@@b@	  public void put(k key, v value) {@b@	    v v = cache.get(key);@b@	    if (v == null) {@b@	      if (cache.size() == capcity) {@b@	        removeElement();@b@	      }@b@	      count.put(key, new HitRate(key, 1, System.nanoTime()));@b@	    } else {@b@	      addHitCount(key);@b@	    }@b@	    cache.put(key, value);@b@	  }@b@@b@	  public v get(k key) {@b@	    v value = cache.get(key);@b@	    if (value != null) {@b@	      addHitCount(key);@b@	      return value;@b@	    }@b@	    return null;@b@	  }@b@@b@	  //移除元素@b@	  private void removeElement() {@b@	    HitRate hr = Collections.min(count.values());@b@	    cache.remove(hr.key);@b@	    count.remove(hr.key);@b@	  }@b@@b@	  //更新访问元素状态@b@	  private void addHitCount(k key) {@b@	    HitRate hitRate = count.get(key);@b@	    hitRate.hitCount = hitRate.hitCount + 1;@b@	    hitRate.lastTime = System.nanoTime();@b@	  }@b@@b@	  //内部类@b@	  class HitRate implements Comparable<HitRate> {@b@	    private k key;@b@	    private int hitCount;@b@	    private long lastTime;@b@@b@	    private HitRate(k key, int hitCount, long lastTime) {@b@	      this.key = key;@b@	      this.hitCount = hitCount;@b@	      this.lastTime = lastTime;@b@	    }@b@@b@	    @Override@b@	    public int compareTo(HitRate o) {@b@	      int compare = Integer.compare(this.hitCount, o.hitCount);@b@	      return compare == 0 ? Long.compare(this.lastTime, o.lastTime) : compare;@b@	    }@b@	  }@b@@b@@b@	  public static void main(String[] args) {@b@	  @b@	    LFUCache<Integer, Integer> cache = new LFUCache<Integer, Integer>(3);@b@	    cache.put(2, 2);@b@	    cache.put(1, 1);@b@@b@	    System.out.println(cache.get(2));@b@	    System.out.println(cache.get(1));@b@	    System.out.println(cache.get(2));@b@@b@	    cache.put(3, 3);@b@	    cache.put(4, 4);@b@@b@	    //1、2元素都有访问次数,放入3后缓存满,加入4时淘汰3@b@	    System.out.println(cache.get(3));@b@	    System.out.println(cache.get(2));@b@	    System.out.println(cache.get(4));@b@@b@	    cache.put(5, 5);@b@	    //目前2访问2次,1访问一次,4访问一次,由于4的时间比较新,放入5的时候移除1元素。@b@	    System.out.println("-------");@b@	    @b@	    @b@	    for(int ckey:cache.cache.keySet()){@b@	    	System.out.println("ckey---"+cache.cache.get(ckey));@b@	    }@b@@b@	  }@b@	  @b@}

控制台打印结果

2@b@1@b@2@b@null@b@2@b@4@b@-------@b@ckey---2@b@ckey---4@b@ckey---5