【随笔·技术】Lambda和匿名内部类

先上代码

//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表达式

推荐阅读更多精彩内容