偶然想到了,之前一直用redis做key-value的缓存,为什么不能用HashMap用作缓存呢?
理由应该是redis中有很多封装好的功能,比如缓存持久化这种。
缓存实现
使用的ConcurrentHashMap做缓存,避免了递归的重复计算:
package cn.mitsuhide.Java8New;
import java.util.concurrent.ConcurrentHashMap;
/** * Created by baidu on 16/10/10. */
public class CacheHelper {
private ConcurrentHashMap<Integer, Integer> cache = new ConcurrentHashMap<>();
public static void main (String [] args) {
CacheHelper ch = new CacheHelper();
System.out.println(ch.fibonaacci(12));
System.out.println(ch.fibonaacci(11));
}
public int fibonaacci (int i) {
if (i == 0 || i == 1) {
return i;
}
// Java 8 Map接口中新增方法
// 首先判断缓存MAP中是否存在指定key的值,如果不存在,会自动调用mappingFunction(key)
// 计算key的value,然后将key = value
// 放入到缓存Map,java8会使用thread-safe的方式从cache中存取记录。
return cache.computeIfAbsent(i, (key) -> {
// 函数式接口,key = i,就是传过来的key,函数中的第一个参数
System.out.println("Compute fibonaacci " + key);
return fibonaacci(key - 1) + fibonaacci(key - 2);
});
}
public ConcurrentHashMap<Integer, Integer> getCache() {
return cache;
}
public void setCache(ConcurrentHashMap<Integer, Integer> cache) {
this.cache = cache;
}
}
Java 8中的新功能
Function接口
如果你正在浏览Java8的API,你会发现java.util.function中 Function, Supplier, Consumer, Predicate和其他函数式接口广泛用在支持lambda表达式的API中。这些接口有一个抽象方法,会被lambda表达式的定义所覆盖。在这篇文章中,我会简单描述Function接口,该接口目前已发布在java.util.function中。
Function接口的主要方法:
R apply(T t) – 将Function对象应用到输入的参数上,然后返回计算结果。
default ‹V› Function‹T,V› – 将两个Function整合,并返回一个能够执行两个Function对象功能的Function对象。
译者注:Function接口中除了apply()之外全部接口如下:
default <V> Function<T,V> andThen(Function<? super R,? extends V> after) 返回一个先执行当前函数对象apply方法再执行after函数对象apply方法的函数对象。
default <V> Function<T,V> compose(Function<? super V,? extends T> before)返回一个先执行before函数对象apply方法再执行当前函数对象apply方法的函数对象。
static <T> Function<T,T> identity() 返回一个执行了apply()方法之后只会返回输入参数的函数对象。
http://ifeve.com/jjava-util-function-java8/
computeIfAbsent方法
在JAVA8的Map接口中,增加了一个方法computeIfAbsent,此方法签名如下:
public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)
Map接口的实现类如HashMap,ConcurrentHashMap,HashTable等继承了此方法,通过此方法可以构建JAVA本地缓存,降低程序的计算量,程序的复杂度,使代码简洁,易懂。
此方法首先判断缓存MAP中是否存在指定key的值,如果不存在,会自动调用mappingFunction(key)计算key的value,然后将key = value放入到缓存Map,java8会使用thread-safe的方式从cache中存取记录。
如果mappingFunction(key)返回的值为null或抛出异常,则不会有记录存入map