You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
3.3 KiB
155 lines
3.3 KiB
import java.util.Map;
|
|
import java.util.HashMap;
|
|
import java.util.Set;
|
|
import java.util.Collection;
|
|
import java.util.Optional;
|
|
import java.util.HashSet;
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* 泛型缓存类 Cache<K, V>
|
|
* 提供简单的键值缓存机制(非线程安全)
|
|
* @param <K> 键的类型
|
|
* @param <V> 值的类型
|
|
*/
|
|
public class Cache<K, V> {
|
|
private final Map<K, V> cache;
|
|
private final int maxSize;
|
|
|
|
// 统计信息
|
|
private long hitCount = 0;
|
|
private long missCount = 0;
|
|
|
|
/**
|
|
* 默认构造方法 - 无容量限制
|
|
*/
|
|
public Cache() {
|
|
this(Integer.MAX_VALUE);
|
|
}
|
|
|
|
/**
|
|
* 带容量限制的构造方法
|
|
*/
|
|
public Cache(int maxSize) {
|
|
this.maxSize = maxSize;
|
|
this.cache = new HashMap<>();
|
|
}
|
|
|
|
/**
|
|
* 存入缓存
|
|
*/
|
|
public void put(K key, V value) {
|
|
if (key == null) {
|
|
throw new IllegalArgumentException("Key cannot be null");
|
|
}
|
|
if (cache.size() >= maxSize && !cache.containsKey(key)) {
|
|
throw new IllegalStateException("Cache is full, no eviction strategy implemented");
|
|
}
|
|
cache.put(key, value);
|
|
}
|
|
|
|
/**
|
|
* 从缓存获取
|
|
*/
|
|
public V get(K key) {
|
|
if (cache.containsKey(key)) {
|
|
hitCount++;
|
|
return cache.get(key);
|
|
} else {
|
|
missCount++;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 使用 Optional 包装返回值(更安全的API)
|
|
*/
|
|
public Optional<V> getOptional(K key) {
|
|
return Optional.ofNullable(get(key));
|
|
}
|
|
|
|
/**
|
|
* 判断缓存中是否存在键
|
|
*/
|
|
public boolean containsKey(K key) {
|
|
return cache.containsKey(key);
|
|
}
|
|
|
|
/**
|
|
* 从缓存中移除
|
|
*/
|
|
public V remove(K key) {
|
|
return cache.remove(key);
|
|
}
|
|
|
|
/**
|
|
* 清空缓存
|
|
*/
|
|
public void clear() {
|
|
cache.clear();
|
|
hitCount = 0;
|
|
missCount = 0;
|
|
}
|
|
|
|
/**
|
|
* 获取缓存大小
|
|
*/
|
|
public int size() {
|
|
return cache.size();
|
|
}
|
|
|
|
/**
|
|
* 判断缓存是否为空
|
|
*/
|
|
public boolean isEmpty() {
|
|
return cache.isEmpty();
|
|
}
|
|
|
|
/**
|
|
* 获取所有键
|
|
*/
|
|
public Set<K> keySet() {
|
|
return new HashSet<>(cache.keySet());
|
|
}
|
|
|
|
/**
|
|
* 获取所有值
|
|
*/
|
|
public Collection<V> values() {
|
|
return new ArrayList<>(cache.values());
|
|
}
|
|
|
|
/**
|
|
* 获取命中率
|
|
*/
|
|
public double getHitRate() {
|
|
long total = hitCount + missCount;
|
|
return total == 0 ? 0.0 : (double) hitCount / total;
|
|
}
|
|
|
|
/**
|
|
* 获取统计信息
|
|
*/
|
|
public CacheStats getStats() {
|
|
return new CacheStats(hitCount, missCount, getHitRate());
|
|
}
|
|
|
|
// 统计信息内部类
|
|
public static class CacheStats {
|
|
public final long hits;
|
|
public final long misses;
|
|
public final double hitRate;
|
|
|
|
public CacheStats(long hits, long misses, double hitRate) {
|
|
this.hits = hits;
|
|
this.misses = misses;
|
|
this.hitRate = hitRate;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return String.format("CacheStats{hits=%d, misses=%d, hitRate=%.2f%%}",
|
|
hits, misses, hitRate * 100);
|
|
}
|
|
}
|
|
}
|