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 * 提供简单的键值缓存机制(非线程安全) * @param 键的类型 * @param 值的类型 */ public class Cache { private final Map 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 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 keySet() { return new HashSet<>(cache.keySet()); } /** * 获取所有值 */ public Collection 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); } } }