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

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);
}
}
}