java lfu缓存,java实现LFU算法

简介

LFU(Least Frequently Used),即最不经常使用,淘汰一定时期内访问次数最少的元素,如果访问次数相同,则比较最新一次的访问时间。

代码实现1

import java.util.Comparator;

import java.util.HashMap;

import java.util.Map;

import java.util.Map.Entry;

public class LFUCache {

private int capacity;

private Map> cache;

public LFUCache(int capacity) {

this.capacity = capacity;

cache = new HashMap<>(capacity);

}

public V get(K key) {

CacheObject cacheObject = cache.get(key);

if (cacheObject == null) {

return null;

}

return cacheObject.getValue();

}

public void put(K key, V value) {

if (capacity == 0) {

return;

}

CacheObject cacheObject = cache.get(key);

if (cacheObject == null) {

if (cache.size() >= capacity) {

//删除最少使用的键,使用次数相等,删除最久未使用的

cache.entrySet().stream()

.min(Comparator.comparing(Entry::getValue))

.ifPresent(e -> {

cache.remove(e.getKey());

});

}

cacheObject = new CacheObject<>(value);

} else {

cacheObject.setValue(value);

}

cache.put(key, cacheObject);

}

@Override

public String toString() {

return cache.toString();

}

static class CacheObject implements Comparable> {

private V value;

private long lastAccessTime;

private int accessCount;

CacheObject(V value) {

setValue(value);

}

V getValue() {

lastAccessTime = System.nanoTime();

accessCount++;

return value;

}

public void setValue(V value) {

this.value = value;

lastAccessTime = System.nanoTime();

accessCount++;

}

@Override

public String toString() {

return value + ":" + accessCount;

}

@Override

public int compareTo(CacheObject o) {

int res = Integer.compare(this.accessCount, o.accessCount);

return res != 0 ? res : Long.compare(this.lastAccessTime, o.lastAccessTime);

}

}

}

存储被缓存对象的访问次数和最后访问时间,当缓存已经达到最大容量时,删除最少访问次数的数据,如果两个数据访问次数相等,删除最后访问时间久的数据。

代码实现2

import java.util.HashMap;

import java.util.Map;

import java.util.TreeSet;

class LFUCache2 {

private int capacity;

private Map> cache;

private TreeSet> treeSet;

public LFUCache2(int capacity) {

this.capacity = capacity;

cache = new HashMap<>(capacity);

treeSet = new TreeSet<>();

}

public V get(K key) {

CacheObject cacheObject = cache.get(key);

if (cacheObject == null) {

return null;

}

treeSet.remove(cacheObject);

V value = cacheObject.getValue();

treeSet.add(cacheObject);

return value;

}

public void put(K key, V value) {

if (capacity == 0) {

return;

}

CacheObject cacheObject = cache.get(key);

if (cacheObject == null) {

if (cache.size() >= capacity) {

//删除最少使用的键,使用次数相等,删除最久未使用的

cache.remove(treeSet.first().key);

treeSet.pollFirst();

}

cacheObject = new CacheObject<>(key, value);

} else {

treeSet.remove(cacheObject);

cacheObject.setValue(value);

}

treeSet.add(cacheObject);

cache.put(key, cacheObject);

}

@Override

public String toString() {

return cache.toString();

}

static class CacheObject implements Comparable> {

private K key;

private V value;

private long lastAccessTime;

private int accessCount;

CacheObject(K key, V value) {

this.key = key;

setValue(value);

}

V getValue() {

lastAccessTime = System.nanoTime();

accessCount++;

return value;

}

public void setValue(V value) {

this.value = value;

lastAccessTime = System.nanoTime();

accessCount++;

}

@Override

public String toString() {

return value + ":" + accessCount;

}

@Override

public int compareTo(CacheObject o) {

int res = Integer.compare(this.accessCount, o.accessCount);

return res != 0 ? res : Long.compare(lastAccessTime, o.lastAccessTime);

}

}

}

相比第一种,使用TreeSet存储访问次数的顺序关系,可以很快的得到最不经常使用的数据。

原文:https://www.cnblogs.com/strongmore/p/14488134.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值