先上代码:
//g=cache(f)
public <T,R> Function<T,R> cache(Function<T,R> f){
final Map<T,R> cache=new HashMap<>();
Function<T,R> g=t->{
if(cache.containsKey(t)){
System.out.println("cached t:"+t);
return cache.get(t);
}
System.out.println("not cached t:"+t);
R r=f.apply(t);
cache.put(t, r);
return r;
};
return g;
// return new Function<T,R>(){
// final Map<T,R> cache=new HashMap<>();
//
// @Override
// public R apply(T t) {
// if(cache.containsKey(t)){
// System.out.println("cached t:"+t);
// return cache.get(t);
// }
// R r=f.apply(t);
// System.out.println("not cached t:"+t);
// cache.put(t, r);
// return r;
// }
//
// };
}
这是网上的一篇文章后面留的习作,题目是传入一个函数f
,返回一个等效的cache版本函数g
。题目本书没什么,只是在我实现的过程中对两种方法有一些感想,列在下面以作备忘。
- 要清楚自由变量和限定变量(约束变量)的区别
- 仅从效果来看lambda写起来简洁,但不如内部类灵活
- 匿名内部类编译后会生成一个顶层类,编译器自动生成的构造函数里,第一个参数必定是包装类的引用,其余的参数依次是捕获的自由变量。
- lambda不会生成另外的类(没有发现class文件)
- lambda对应invokedaynamic指令
一些扩展阅读的博客文章
通过字节码分析JDK8中Lambda表达式编译及执行机制
java8 lambda学习笔记之编译与运行过程
Java8学习笔记(4) -- Lambda表达式实现方式
Lambda表达式
网友评论