Java 8 lambdas

来源:互联网 发布:知乐的全部小说目录 编辑:程序博客网 时间:2024/06/05 03:01
lambda表达式与函数和对象都一样有属性的,取决于你观察的角度
从概念上讲的话:lambda其实就是一个函数 , It is an unnamed piece of reusable functionality 它就是一个未命名的的一块可以重复使用的函数(代码段?),
它具有签名和一个方法体,但是就是没有函数名...
当把一个lambda表达式作为 一个参数传递给方法,这个方法会把lambda表达式作为一个对象来处理的
Java是非面向函数语言,但是却引入了一些特殊的接口来实现面向函数的语言的功能,Java把这些特殊的接口称为函数接口,即,SAM类型 single abstract method
其实在Java中也是有挺多这样接口的,Runnale就是一个经典的案例. 因为它需要实现一个run方法.类似的还有Readable, Callable, Iterable, Closeable, 
Flushable, Formattable, Comparable, Comparator.

作为Java的函数接口以及lambda表达式,他们都是只处理一个独立的函数的.例如runnable就是只处理一个run函数的.那么Java语言设计者设计lambda表达式其实就是
为了方便简洁美观而已,因为在编译的时候,编译器其实就是把lambda表达式转化成一个标准的functional interface的.(好像有点浪费s表情?),不过呢,这个转换是自动
的,lambda表达式的转化是可行的(转化过程是一个编译的活动,不会消耗运行的时间的)

lambda vs 匿名内部类
两者在语法上大不同,
Anonymous inner class:
File[] fs = myDir.listFiles(
new FileFilter() {
public boolean accept(File f) { return f.isFile(); }
}
);

Lambda expression
File[] files = myDir.listFiles( (File f) -> {return f.isFile();} ); or 
File[] files = myDir.listFiles( f -> f.isFile() );
多简洁啊
在运行匿名内部类的时候需要:
类加载 内存申请 对象初始化 调用非静态方法 (看起来很麻烦的样子?但是我已经习惯了耶)
而运行lambda需干嘛呢? 首先肯定是转化咯,就是把lambda表达式转化成functional interface,最终被调用(注意了,the functional interface
conversion is a pure compile-time activity and incurs no cost at runtime)这段话的意思即,转化的过程是一个纯粹的编译活动,根本不会花费运行的时间的
由此可见 lambda在减少运行时间上市比匿名内部类是有优势的...

在变量绑定角度看:
匿名内部类内部是可以访问外部的final变量,即内部类是可以访问到封闭的上下文的所有的final变量.(所以这些final变量一旦付了值千万不要尝试去修改他们的值,这样会报错的)
而lambda表达式的访问原则和匿名内部类也是一样一样的,但是!!!!!!!!!但是有唯一的区别就是!!!!如果lambda表达式引用外部的变量的话,不要求这个变量是final修饰过的,但是
也要求这个变量不能被修改,因为!!因为编译器会自动的识别这个变量是final类型的(摔!有什么区别吗?还不如严谨一点,免得出差错...) 即使这个变量没有被final修饰但是你也
不要以为他就是普普通通的变量,在编译的时候系统会给它添加上final类型的~
注意的是:在Java8,匿名内部类也是不在需要给变量加上final修饰符了,编译器变聪明了...所以呢--------变量绑定这个角度看来说,两者没区别啦

那就再从"范围"这个角度来看两者的区别吧

匿名内部类的内部是属于自己的一个环境,在内部类外部定义的一个变量在内部类内部依旧可以定义同样变量名,因为内外之分后就产生两个不同的"环境',
但是在lambda里面就不是这样的了,在lambda表达式中的环境其实就是对外open的,即,lambda的body内虽然看起来是用花括号括起来但是括号内的环境是和外部环境一致的
因此在lambda外部定义了===> int a=10;后就再也不能再lambda内部定义int a =20;了就相当于一个a定义了两次,因此产生了错误...时刻记住,lambda是整个enclosing context的一部分
这样的话 super() and this 在两者之间也产生的差异 ====>匿名内部类中的super()是指内部类的超类,this是指内部类自身 但是在lambda中this指的是包含lambda表达式的context
super指的也是外部环境类的超类
作者的一个预言,以后的IDE会帮助用户把匿名内部类转换成lambda表达式


为何我们需要lambda表达式?
why we need lambdas ? 根据翻译得:
因为JDK要进化要演变尤其是JDK的集合框架需要升级了(这个理由很吊,不过我真的没觉得我的)

为了更好地应对未来的多核多CPU的机器,JDK要更好的支持并行操作
在容器类中一个最大的变化就是遍历器的改变,一般我们习惯的使用的是实例化一个容器类后调用他的iterator方法获取遍历器,然后使用遍历器单线程的遍历里面的元素,
但是到了Java8中就改变了, 之前的遍历器属于external iteration对应的有了一个internal iteration概念.(经由流这个概念而生成的)\
让我们来看看两者之间的区别吧~
外部iteration就不需要说啦,说说internal iteration吧,这个序列自己定义了自己的元素如何被访问到,然后user只需要
responsible for specifying what has to be applied to each element in the sequence.//妈蛋有词组忘了如何翻译啊 等谷歌吧
流文件将会在Java8中大放异彩!!!因为它的链式编程很强大!主要提供的几个函数都很厉害!!!
一般是这样的 ====> 先把对象编程流对象->filter负责过滤工作->map负责把过滤出来的对象映射成一个文件->最后对文件进行遍历工作filter(满足条件的才会保留否则被剔除)
0 0
原创粉丝点击