Java小技巧:创建带缓存的过程
- 手机
- 2025-07-21 19:11:41

在平常开发中,我们经常遇到这样一类过程:有一定计算量,被频繁调用,但对于任意一个参数,结果是恒定的(换句话说,就是纯函数),为了减少频繁调用的性能开销,我们可能会写出这样的代码:
public class ExampleUnitTest { Map<Integer, String> cacheMap = new HashMap<>(); public String doTaskWithCache(Integer i) { String s = cacheMap.get(i); // 先检查是否有缓存 if (s == null) { s = calculateResult(i); cacheMap.put(i, s); // 计算结果存到缓存里 } return s; } }但是,这样写的话,每次有需要带缓存的函数,创建缓存以及检查结果是否已缓存的那代码就得重写一遍,想想就有些麻烦,本文就介绍一个简单的工具Memorizer来简化这个过程。
Memorizer 的实现因为实现代码比较少,我们看实现代码
public class Memorizer<T, V> { public static <T, V> Function<T, V> memorize(Function<T, V> function) { Map<T, V> cacheMap = new HashMap<>(); return (T t) -> Optional.ofNullable(cacheMap.get(t)).orElseGet(() -> { V value = function.apply(t); cacheMap.put(t, value); return value; }); } public static <T, V> Function<T, V> weakMemorize(Function<T, V> function) { Map<T, V> cacheMap = new WeakHashMap<>(); return (T t) -> Optional.ofNullable(cacheMap.get(t)).orElseGet(() -> { V value = function.apply(t); cacheMap.put(t, value); return value; }); } }这个工具有两个方法,都接受一个单参函数作为参数,并返回一个同类型的单参函数,意思是:传入要缓存的函数,返回该函数的带缓存的版本。
weakMemorize方法返回的函数的缓存可能会被回收,适合那些内存资源紧张或者想减少内存压力的场景,不过这也会导致一定概率的缓存失效的情况。
Memorizer 的使用我们用``来改写上面的例子,就成了:
public class ExampleUnitTest { private Function<Integer, String> doTaskWithCache = (i) -> calculateResult(i); } 写在最后这里只给出了单参数的实现,如果要考虑多参数的缓存,可以尝试用下面这种方式扩展:
public class Memorizer<T, V> { public static <T1, T2, V, K> BiFunction<T1, T2, V> memorize(BiFunction<T1, T2, V> function, BiFunction<T1, T2, K> keyExtractor) { Map<K, V> cacheMap = new HashMap<>(); return (t1, t2) -> { K key = keyExtractor.apply(t1, t2); return Optional.ofNullable(cacheMap.get(key)).orElseGet(() -> { V value = function.apply(t1, t2); cacheMap.put(key, value); return value; }); }; } public static <T1, T2, V, K> BiFunction<T1, T2, V> weakMemorize(BiFunction<T1, T2, V> function, BiFunction<T1, T2, K> keyExtractor) { Map<K, V> cacheMap = new WeakHashMap<>(); return (t1, t2) -> { K key = keyExtractor.apply(t1, t2); return Optional.ofNullable(cacheMap.get(key)).orElseGet(() -> { V value = function.apply(t1, t2); cacheMap.put(key, value); return value; }); }; } }Java小技巧:创建带缓存的过程由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Java小技巧:创建带缓存的过程”
上一篇
ansible模块